MacOS 上的 Clang 编译错误

Clang compilation error on MacOS

这个问题似乎只出现在 MacOS 上,在 linux 上也可以使用 clang 进行编译。

下面的代码是一个简化但演示了这个问题,

#include<iostream>
int index = 0;
int main()
{
    std::cout << index << std::endl;
}

编译时抛出此错误:

    main.cpp:2:5: error: redefinition of 'index' as different kind of symbol
int index = 0;
    ^
/usr/include/strings.h:73:7: note: previous definition is here
char    *index(const char *, int) __POSIX_C_DEPRECATED(200112L);
         ^
main.cpp:5:18: warning: address of function 'index' will always evaluate to
      'true' [-Wpointer-bool-conversion]
    std::cout << index << std::endl;
              ~~ ^~~~~
main.cpp:5:18: note: prefix with the address-of operator to silence this warning
    std::cout << index << std::endl;
                 ^
                 &
1 warning and 1 error generated.

这些是使用的编译器参数:

clang++ -std=c++11 main.cpp -o test

当使用 stdio 删除 iostream 或什么都不删除时,代码会按预期进行编译。他们是解决这个问题的方法还是我必须重命名我的变量以避免这个问题?

我确实找到了 this,但我已经在使用 C++11 标志,而 -std=c11 标志似乎对 C++ 代码无效。

当您包含 <iostream> 时,您使用的 clang/xcode 的特定版本恰好包含 <strings.h> header。 <strings.h> 在全局范围内提供了一个名为 index() 的函数。因此,您不能在全局范围内也声明同名变量。

重命名变量,或将其移动到 main():

#include <iostream>

int main()
{
    int index = 0;
    std::cout << index << std::endl;
}

这是可行的,因为当一个变量与其他变量具有相同的标识符但在不同的范围内时,它会被视为完全不同的实体。

为了举例说明其工作原理,请考虑以下代码:

#include <iostream>

int myVar = 0;

int main()
{
    int myVar = 1;
    std::cout << myVar << '\n';
    std::cout << ::myVar << '\n';
}

这将打印:

1
0

因为 myVar 指的是局部变量,而 ::myVar 指的是全局范围的变量。

Is their a way to fix this or will I have to rename my variable to avoid this?

C++ 专门提供命名空间来避免名称之间的冲突。您可以为您的变量创建一个:

#include<iostream>

namespace MyGlobals {
    int index = 0;
}

int main()
{
    std::cout << MyGlobals::index << std::endl;
}