如何让Xcode考虑我定义的值?

时间:2013-08-27 17:22:50

标签: c xcode

如何让Xcode考虑我的定义的值来正确折叠我的代码? Xcode似乎考虑了一些未编译的代码作为代码的一部分 - 导致我遇到一些问题:(

示例:

#include <stdio.h>

#define LIE_TO_THE_USER   1

void foobar(int argc)
{ // A
#if LIE_TO_THE_USER
    if (0) { // B
#else
    if (argc > 0) { // C
#endif
        printf("argc is greater than 0\n");
    } // D
    else
    { // E
        printf("argc is not greater than 0\n");
    } // F
} // G

int main(int argc, const char * argv[])
{
    foobar(argc);
    return 0;
}

此代码编译......但是很难处理。

就Xcode而言,它将括号C和D折叠在一起,将E和F折叠在一起,并将C和G折叠在一起(而不是折叠A和G)。此外,在#if #else #endif之后声明的任何内容(在这种情况下只是main)在这种情况下不会显示。

在Visual Studio中,它只会使if (argc> 0 ) { // C变灰并忽略它。但Xcode似乎认为它是代码的一部分。我找到了2个解决方法:

void foobar(int argc)
{
#if LIE_TO_THE_USER
    if (0)
#else
    if (argc > 0)
#endif
    {
        printf("argc is greater than 0\n");
    }
    else
    {
        printf("argc is not greater than 0\n");
    }
}

///  OR

void foobar(int argc)
{
#if LIE_TO_THE_USER
    if (0) {
#else
    if (argc > 0) {
#endif
        printf("argc is greater than 0\n");
    }
    else
    {
        printf("argc is not greater than 0\n");
    }
#if 0
    }
#endif
}

然而,这个问题在我的项目中很常见。所以我想找到自动解决这个问题,而不必担心添加变通方法。有没有人知道如何配置Xcode以忽略诸如if (argc > 0) {

之类的行

提前致谢:)

2 个答案:

答案 0 :(得分:2)

这是宏观可怕的原因之一;您可以任意处理令牌流,并且不一定要尊重语言的结构。

Visual Studio完全忽略了预处理器所吃的任何东西,这意味着它可以可靠地理解当前定义下的代码结构,但不了解已禁用的代码。 Xcode试图变得更聪明并且理解整个程序,但是当你使用真正破坏语言结构的宏时,这种方法效果很差。

C ++已经足够难以使用工具,并且预处理器的基本特性使其更糟糕,因为它实际上使得相同的C ++源可以产生任意多个程序。您可以通过尽量减少预处理器的使用,并将使用限制在最简单和最常规的方式来避免此问题,以便工具可以理解它们。


在这种情况下,我想我会选择以下内容:

void foobar(int argc)
{
    static constexpr bool tell_the_truth = false;

    if (tell_the_truth && argc > 0)
    {
        printf("argc is greater than 0\n");
    }
    else
    {
        printf("argc is not greater than 0\n");
    }
}

或者如果您希望能够从编译命令配置它,您可以使用:

static constexpr bool tell_the_truth = !LIE_TO_THE_USER

这样您就可以使用-DLIE_TO_THE_USER=true-DLIE_TO_THE_USER=false等标记。

这种方法的好处是工具对该程序的理解,AST,实际上代表了预期的程序,并没有从根本上改变配置。

答案 1 :(得分:1)

您可以使用有条件编译的宏减少看起来像条件​​编译到Xcode的代码量,如下所示:

#define LIE_TO_THE_USER   1
...
#if LIE_TO_THE_USER
    #define CONDITIONAL_LIE(A,B) (A)
#else
    #define CONDITIONAL_LIE(A,B) (B)
#endif

掌握此宏后,您可以按如下方式重写if

if (CONDITIONAL_LIE(0, argc > 0))
{
    printf("argc is greater than 0\n");
}
else
{
    printf("argc is not greater than 0\n");
}

代码会有条件地编译成相同的输出,但Xcode会认为它是常规的if。这对读者来说也更清晰。