如何让Xcode在不匹配的返回类型上生成警告(或错误)?

Aly*_*hak 2 xcode compiler-errors objective-c compiler-warnings type-mismatch

我只是在方法的返回类型的类型中进行了代码更改,并指望编译器显示警告,这将允许我找到并修复现在不匹配的位置.但没有警告.在我的设置中,我发现所有构建类型的"不匹配的返回类型"已经是"是",因此我决定将其更改为"是(视为错误)"并进行重建.构建结果中仍然没有任何迹象.

然后我将"将警告视为错误"更改为"是",这会产生一些有用的错误消息,但没有不匹配的警告.也许我对编译器和Objective-C返回类型一无所知,但是当我的方法指定应返回NSNumber*时,似乎不应该接受bool.

这是我的代码:

+(NSNumber*) compilerCompletelyFineWithThis
{
    if ([m_session tryThis])
    {
        return [m_session goGetSumthin];
    }
    else
        return false;
}
Run Code Online (Sandbox Code Playgroud)

文档建议不匹配的返回类型与GCC_WARN_ABOUT_RETURN_TYPE相关联,但不清楚它强制执行哪些规则.

在我的构建设置的警告部分下面的图片中,请注意相关设置.我为所有构建打开了"将警告视为错误"和"不匹配的返回类型".

在此输入图像描述

当我违反方法定义和调用代码之间的这种契约时,有没有办法让Xcode让我知道?

rob*_*off 6

悲伤的消息......这里的问题不在于"不匹配的返回类型"警告/错误设置.

问题是,false实际上是一个#define0.您可以stdbool.h在Xcode 8.3.3中找到隐藏在此路径中的定义:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/8.1.0/include/stdbool.h

因为它是一个预处理器定义,它就会从改变false0编译器的语义分析的部分看到它之前.

在C中,您可以使用裸文字0作为空指针.因此,在您的情况下,false被视为空指针,NSNumber并且是合法的返回值.

即使您使用首选的Objective-C布尔值NO,仅此一项也无法解决问题.NO是一个#definefor __objc_no(参见/usr/include/objc/objc.h),它是一个clang扩展,有效地充当文字0(但允许编译器使用转换@YES@NO正确的单例).

要获得警告,您需要采取三个步骤:

  1. 添加-Wnon-literal-null-conversion到"其他C标志"构建设置.
  2. 返回NO而不是false.
  3. 声明你的函数返回_Nonnull.

结果:

+(NSNumber * _Nonnull) compilerCompletelyFineWithThis {
    return NO;
    // error: Expression which evaluates to zero treated as a null pointer constant of type 'NSNumber * _Nonnull'
}
Run Code Online (Sandbox Code Playgroud)

从Xcode 9开始,您可以打开"Implicit Non-Literal Null Conversions"构建设置,而不是修改"Other C Flags".