c++ - 将常量定义为函数会导致 header = 坏主意?

标签 c++

在我们的一个项目中广泛使用的包含文件中,我们有这些方便的常量:

const double kPi        = asin(1.0) * 2.0;
const double kPiHalf    = asin(1.0);
const double kDeg2Rad = asin(1.0) / 90.0;
const double kRad2Deg = 90.0 / asin(1.0);

在运行时使用函数结果计算一次(精确的)常量是个坏主意吗?

我们收到的一些最近的故障转储(在 OS X 上)看起来很狡猾 - 尽管发生了崩溃,但它们有一个堆栈帧,其中包含 const double kRad2Deg 行的地址在深层在应用程序中的某个地方向上堆栈跟踪。很奇怪。

在启动阶段很早就调用数学函数是否可能搞砸事情?

我知道我们可以用常量替换函数调用,但我想大致了解问题(如果有的话)。

最佳答案

简答,使用<cmath> .

长答案:在静态初始化器中调用函数是一个棘手的问题,因为函数本身可能依赖于静态初始化的数据并且初始化顺序未定义,所以一般,这是不好的做法.

foo.cpp

namespace {std :: vector <int> data;}
int foo (int i) {
    data .push_back (i);
    return data .size ();
}

酒吧.cpp

int f = foo (123);

这很危险,因为 data可能还没有 build 。 foo.cpp 的安全版本是

namespace {
    std :: vector <int> & data () {
        static std :: vector <int> d;
        return d;
    }
}
int foo (int i) {
    data () .push_back (i);
    return data () .size ();
}

如果您不能保证所涉及的所有函数都遵循此模式,那么您就不安全。

另一方面,静态内置类型在任何事情发生之前都会将它们的值加载到内存中,所以它们没问题。

foo.cpp

const double pi = M_PI;

酒吧.cpp

int main () {
    double foo = pi;
}

这很好。

还是用<cmath> ,标准要求其值尽可能准确。表演 90.0/asin(1.0)只会加剧错误。

关于c++ - 将常量定义为函数会导致 header = 坏主意?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8900274/

相关文章:

c++ - 如何在 QT[C++] 中从 linux 机器连接 SQL Server 2008 R2?

c++ - operator->智能指针的返回值

c++ - Boost Enum 256 元素限制

java - 即使在添加 def 后,外部 "C"也会给出错误 "Linkage specification is not allowed"。在头文件中?

c++ - 未定义对 web::json::value::object 的引用,即使包含 json.h

c++ - 从另一个类的构造函数将数组传递给类函数

c++ - 如何将char字符串转换为std字符串

c++ - 在 C++ 中将一个字符从 vector 插入到字符串

c++ - 迭代器有效性,在 std::set 中调用 erase() 之后

c++ - GTKmm3 (GTK+ 3 C++) 编译但在运行时抛出 GLib-GIO-CRITICAL 错误