C ++积分常数+选择运算符=问题! [英] C++ integral constants + choice operator = problem!
问题描述
我最近在一些正在开发的大型程序中发现了一个恼人的问题;我想了解如何解决它在一个最好的方式。我将代码下降到以下最小示例。
I have recently discovered an annoying problem in some large program i am developing; i would like to understand how to fix it in a best way. I cut the code down to the following minimal example.
#include <iostream>
using std::cin;
using std::cout;
class MagicNumbers
{
public:
static const int BIG = 100;
static const int SMALL = 10;
};
int main()
{
int choice;
cout << "How much stuff do you want?\n";
cin >> choice;
int stuff = (choice < 20) ? MagicNumbers::SMALL : MagicNumbers::BIG; // PROBLEM!
cout << "You got " << stuff << "\n";
return 0;
}
我在gcc 4.1.2中获取链接错误, O1,但使用-O2或-O3编译时,一切都正常。
I get link errors in gcc 4.1.2 when compiling with -O0 or -O1 but everything is OK when compiling with -O2 or -O3. It links well using MS Visual Studio 2005 regardless of optimization options.
test.cpp :(。text + 0xab):未定义的引用` MagicNumbers :: SMALL'
test.cpp:(.text+0xab): undefined reference to `MagicNumbers::SMALL'
test.cpp :(。text + 0xb3):未定义引用`MagicNumbers :: BIG'
test.cpp:(.text+0xb3): undefined reference to `MagicNumbers::BIG'
我查看了中间汇编代码,是的,非优化代码认为SMALL和BIG作为外部int变量,而优化的代码使用实际数字。以下每个更改都会修复问题:
I looked at the intermediate assembly code, and yes, the non-optimized code regarded SMALL and BIG as external int variables, while the optimized one used the actual numbers. Each of the following changes fixes the problem:
-
使用枚举而不是int作为常量:
enum { SMALL = 10}
在每次使用时投射常量(任何一个): :: SMALL
或(int)MagicNumbers :: BIG
或甚至 MagicNumbers :: SMALL + 0
Cast the constant (any one) at each usage: (int)MagicNumbers::SMALL
or (int)MagicNumbers::BIG
or even MagicNumbers::SMALL + 0
使用巨集: #define SMALL 10
不使用选择运算符: if(choice< 20)stuff = MagicNumbers :: SMALL; else stuff = MagicNumbers :: BIG;
,它不是理想的,因为我们实际上使用uint32_t而不是int这些常量,enum是int的同义词。但是我真正想问的是:它的错误是什么?
I like the first option best (however, it's not ideal because we actually use uint32_t instead of int for these constants, and enum is synonymous with int). But what i really want to ask is: whose bug is it?
我不明白静态整数常数是如何工作的?
Am i the one to blame for not understanding how static integral constants work?
我应该指责gcc并希望修复(或者最新版本已经有一个修复,或者有一个模糊的命令行参数,使这项工作)?
Should i blame gcc and hope for a fix (or maybe the latest version already has a fix, or maybe there is an obscure command-line argument to make this work)?
同时,我只是编译我的代码优化,这是一个痛苦的调试:-O3
Meanwhile, i just compile my code with optimizations, and it's a pain to debug :-O3
推荐答案
尽管传统的意见,我发现 static const int ...
总是给我更多的头痛比旧 enum { BIG = 100,SMALL = 10};
。和C ++ 11提供强类型的枚举,我现在有更少的原因使用 static const int ...
。
In spite of the conventional advice, I have found that static const int ...
invariably gives me more headaches than good old enum { BIG = 100, SMALL = 10 };
. And with C++11 providing strongly-typed enums, I now have even less cause to use static const int ...
.
这篇关于C ++积分常数+选择运算符=问题!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!