cmath和y0变量名称未编译

Его*_*дев 5 c++ cmath

我得到了一个名为变量y0并包含cmath的变量,在g++不带任何参数的情况下进行编译时,出现编译错误

error: invalid operands of types ‘double(double) throw ()’ and ‘double’ to binary ‘operator+’ y = y0 + R; ~~~^~~

为了进行实验,我删除了cmath,其中包括所有内容,一切正常。

#include <iostream>
#include <cmath>

double y0, y, R;
int main() {
    std::cin >> y0 >> R; 
    y = y0 + R;
}
Run Code Online (Sandbox Code Playgroud)

Kam*_*Cuk 5

您使用的编译器g ++ 无条件定义了_GNU_SOURCE宏。宏_GNU_SOURCE根据man feature_test_macros运行。宏使GNU C库实现glibc定义了许多额外的gnu扩展,这些扩展污染了全局名称空间。在glibc包含文件中cmath包括math.h

这些gnu扩展之一是例如double y0(double)函数,它是用于计算Bessel函数的gnu扩展。如果尝试y0在全局名称空间中将自己的符号声明为其他符号,则编译器应抱怨为y0符号声明的类型冲突。您看到的错误之一是因为符号y0被声明为函数,所以编译器无法+添加它。

正确的解决方法是正确解决glibc中的问题,并帮助世界各地的开发人员-修补glibc和g ++时不要在c ++中编译时导出gnu扩展函数。如仍指示的libstdc ++常见问题解答We'd like to find a cleaner solution, but nobody yet has contributed the time

另一个解决方法是_GNU_SOURCE使用-U_GNU_SOURCE编译器开关在g ++中取消定义符号。这会导致使用时数学模板函数中未声明符号的错误,因为glibc / libstdc ++中的许多数学函数实现都使用gnu扩展。另一个解决方法是使用不受此问题困扰的另一个标准C ++库实现。

一个现实的解决方法是不要y0在全局名称空间中声明符号。只需在其周围添加一个名称空间并正确引用它即可:

namespace my {
   double y0;
}
int main() { 
   my::y0 = 1;
}
Run Code Online (Sandbox Code Playgroud)