1

如何让 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) {?

提前致谢 :)

4

2 回答 2

2

This is one of the reasons macros are horrible; You can arbitrarily mess with the token stream and aren't bound to respect the language's structure.

Visual Studio is just completely ignoring whatever is eaten by the preprocessor, which means it reliably understands the structure of the code under the current defines but has no understanding of the code that's disabled. Xcode is trying to be smarter and to understand the entire program, but this works poorly when you use macros that really subvert the language's structure.

C++ is already hard enough for tools to work with, and the fundamental nature of the preprocessor makes it worse by essentially making it so that the same C++ source can produce arbitrarily many programs. You can avoid this problem by minimizing use of the preprocessor, and restricting uses to the simplest and most conventional, so that tools are likely to understand them.


In this case I think I would go with something like:

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");
    }
}

Or if you want to be able to configure this from the compilation command you can use:

static constexpr bool tell_the_truth = !LIE_TO_THE_USER

So that you can use a flag such as -DLIE_TO_THE_USER=true or -DLIE_TO_THE_USER=false.

The benefit of this approach is that tools' understanding of this program, the AST, actually represents the intended program and doesn't fundamentally change between configurations.

于 2013-08-27T18:45:50.497 回答
1

你可以通过使用条件编译的宏来减少看起来像条件​​编译的代码量,如下所示:

#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. 这对读者来说也看起来更干净。

于 2013-08-27T17:32:37.610 回答