关于静态常量的c ++标准 [英] the c++ standard on static constants
问题描述
我正在试图找出g ++是否有错误。等等,不要离开,
这是标准的C ++问题,我保证。
这个程序将在mingw / g ++下编译和链接3.4.2,但无法在Linux / g ++ 3.3.3下链接
。
-------------- -------------------------------
#include< iostream>
#include< utility>
class foo {
private:
char sram [0x2000];
static const int A = 0x8;
static const int B = 0x1FF8;
foo(){
sram [8] = 1;
sram [9] = 2;
sram [0x1FF8] = 3;
sram [0x1FF9] = 4;
}
std :: pair< unsigned char,unsigned char>方法(bool冗余)const {
int offset =(冗余?B:A);
返回std :: pair< unsigned char,
unsigned char>(sram [offset],sram [offset + 1]);
}
};
int main(int,char **){
foo f;
std :: pair< unsigned char,unsigned char> p1(f.method(false));
std :: pair< unsigned char,unsigned char> p2(f.method(true));
std :: cout<< p1 =("<<(int)p1.first<<","
<<(int)p1.second<<" )\ n" ;;
std :: cout<< " p2 =("<<(int)p2.first<<","
<<(int)p2.second<<"" )\ n" ;;
返回0;
}
------------ ---------------------------------
原因在于mingw / g ++ 3.4.2,静态常量A和B在编译期间被替换为
,并且不需要存储空间。链接器
因此不需要找到它们。但是,Linux / g ++ 3.3.3会生成
代码,要求它们有存储空间。
我应该为这些常量声明存储空间,或者这是否是b $ b合法在这里假设它们将成为编译时的constnats? C ++标准说什么是什么?
谢谢,
- 约翰拉特利夫
John Ratliff写道:我正在试图找出g ++是否有错误。等等,不要离开,这是一个标准的C ++问题,我保证。
这个程序将在mingw / g ++ 3.4.2下编译和链接,但
无法在Linux / g ++ 3.3.3下链接。
------------------------------ ---------------
#include< iostream>
#include< utility>
class foo {
private:
char sram [0x2000];
public:
static const int A = 0x8;
static const int B = 0x1FF8;
foo(){
sram [8] = 1;
sram [9] = 2;
sram [0x1FF8] = 3;
sram [0x1FF9] = 4;
}
std :: pair< unsigned char,unsigned char>方法(bool冗余)
const {int offset =(冗余?B:A);
返回std :: pair< unsigned char,
unsigned char>(sram [offset] ],sram [offset +
1]); }
};
int main(int,char **){
foo f;
std :: pair< unsigned char,unsigned char> p1(f.method(false));
std :: pair< unsigned char,unsigned char> p2(f.method(true));
std :: cout<< " p1 =("<<(int)p1.first<<","
<<(int)p1.second<<")\ n" ;;
std :: cout<< " p2 =("<<(int)p2.first<<","
<<(int)p2.second<<")\ n" ;;
返回0;
}
---------------------------- -----------------
该计划格式正确。 A和B从不在类定义之外使用,因此不需要定义它们。这就是标准1998年版本的
。在2003年的版本(IIRC)中有一点改变了,但给了程序员更多的回旋余地。
原因是在mingw / g ++ 3.4.2中,静态常量A和B
在编译期间被替换,并且不需要存储空间。因此,
链接器不需要找到它们。但是,Linux / g ++ 3.3.3
会生成需要存储空间的代码。
用什么方式?你能想出试图引用它们的是什么吗?
我应该为这些常量声明存储空间,还是在这里合法地假设它们将成为编译时的constnats? C ++标准说的是什么?
由于他们的地址从未被采用过,''foo :: A''和''foo :: B '',实际上是
,不需要存储的编译时常量表达式。
因此,不需要在对象之外定义对象。类
定义。 g ++ 3.3.3可能太旧了。即使使用1998版的C ++
标准,它在这个特殊情况下甚至太旧且不符合b $ b。该标准被修改为允许const静态仅在类别定义中定义,如果他们的地址不被采用_even_
如果他们被使用的话。课外。 [虽然我太懒了,但是看起来很难在标准中... ...
V
Victor Bazarov写道:John Ratliff写道:
我正在试图找出g ++是否有错误。等等,不要离开,这是一个标准的C ++问题,我保证。
这个程序将在mingw / g ++ 3.4.2下编译和链接,但
无法在Linux / g ++ 3.3.3下链接。
------------------------------ ---------------
#include< iostream>
#include< utility>
class foo {
private:
char sram [0x2000];
public:
static const int A = 0x8;
static const int B = 0x1FF8;
foo(){
sram [8] = 1;
sram [9] = 2;
sram [0x1FF8] = 3;
sram [0x1FF9] = 4;
}
std :: pair< unsigned char,unsigned char>方法(bool冗余)
const {int offset =(冗余?B:A);
返回std :: pair< unsigned char,
unsigned char>(sram [offset] ],sram [offset +
1]); }
};
int main(int,char **){
foo f;
std :: pair< unsigned char,unsigned char> p1(f.method(false));
std :: pair< unsigned char,unsigned char> p2(f.method(true));
std :: cout<< " p1 =("<<(int)p1.first<<","
<<(int)p1.second<<")\ n" ;;
std :: cout<< " p2 =("<<(int)p2.first<<","
<<(int)p2.second<<")\ n" ;;
返回0;
}
---------------------------- -----------------
该计划格式正确。 A和B从不在类定义之外使用,所以不需要定义它们。这就是1998年标准版本所说的内容。它在2003版本(IIRC)中有所改变,但为程序员提供了更多的余地。
原因在于mingw / g ++ 3.4。 2,静态常量A和B
在编译期间被替换,并且不需要存储空间。因此,
链接器不需要找到它们。但是,Linux / g ++ 3.3.3
生成的代码需要它们有存储空间。
用什么方式?你能想出试图引用它们的是什么吗?
这是从Linux / g ++ 3.3.3为foo :: method生成的汇编当
使用g ++ -S temp.cc.没有声明额外的优化,但是如果你做-O2那么它不会被b $ b修复它。真正愚蠢的是,如果用if语句替换
三元运算符,它会将A和B视为
编译时常量。
------------------------------------------ -----------
_ZNK3foo6methodEb:
..LFB1535:
pushl%ebp
..LCFI14:
movl%esp,%ebp
..LCFI15:
subl
< blockquote> 24,%esp
..LCFI16:
movl 16(%ebp),%eax
movb%al,-1( %ebp);堆叠多余
cmpb
I''m trying to find out whether g++ has a bug or not. Wait, don''t leave,
it''s a standard C++ question, I promise.
This program will compile and link fine under mingw/g++ 3.4.2, but fails
to link under Linux/g++ 3.3.3.
---------------------------------------------
#include <iostream>
#include <utility>
class foo {
private:
char sram[0x2000];
public:
static const int A = 0x8;
static const int B = 0x1FF8;
foo() {
sram[8] = 1;
sram[9] = 2;
sram[0x1FF8] = 3;
sram[0x1FF9] = 4;
}
std::pair<unsigned char, unsigned char> method(bool redundant) const {
int offset = (redundant ? B : A);
return std::pair<unsigned char,
unsigned char>(sram[offset], sram[offset + 1]);
}
};
int main(int, char **) {
foo f;
std::pair<unsigned char, unsigned char> p1(f.method(false));
std::pair<unsigned char, unsigned char> p2(f.method(true));
std::cout << "p1 = (" << (int)p1.first << ","
<< (int)p1.second << ")\n";
std::cout << "p2 = (" << (int)p2.first << ","
<< (int)p2.second << ")\n";
return 0;
}
---------------------------------------------
The reason is that in mingw/g++ 3.4.2, the static constants A and B are
replaced during compile time and didn''t need storage space. The linker
therefore didn''t need to find them. However, Linux/g++ 3.3.3 generates
code that requires them to have storage space.
Am I supposed to declare storage space for these constants, or is it
legal here to assume they will become compile-time constnats? What does
the C++ standard say?
Thanks,
--John Ratliff
John Ratliff wrote:I''m trying to find out whether g++ has a bug or not. Wait, don''t
leave, it''s a standard C++ question, I promise.
This program will compile and link fine under mingw/g++ 3.4.2, but
fails to link under Linux/g++ 3.3.3.
---------------------------------------------
#include <iostream>
#include <utility>
class foo {
private:
char sram[0x2000];
public:
static const int A = 0x8;
static const int B = 0x1FF8;
foo() {
sram[8] = 1;
sram[9] = 2;
sram[0x1FF8] = 3;
sram[0x1FF9] = 4;
}
std::pair<unsigned char, unsigned char> method(bool redundant)
const { int offset = (redundant ? B : A);
return std::pair<unsigned char,
unsigned char>(sram[offset], sram[offset +
1]); }
};
int main(int, char **) {
foo f;
std::pair<unsigned char, unsigned char> p1(f.method(false));
std::pair<unsigned char, unsigned char> p2(f.method(true));
std::cout << "p1 = (" << (int)p1.first << ","
<< (int)p1.second << ")\n";
std::cout << "p2 = (" << (int)p2.first << ","
<< (int)p2.second << ")\n";
return 0;
}
---------------------------------------------
The program is well-formed. ''A'' and ''B'' are never used outside of
the class definition, so they don''t need to be defined. That''s what
1998 version of the Standard used to say. It was changed a bit in the
2003 version (IIRC) but to give programmers even more leeway.
The reason is that in mingw/g++ 3.4.2, the static constants A and B
are replaced during compile time and didn''t need storage space. The
linker therefore didn''t need to find them. However, Linux/g++ 3.3.3
generates code that requires them to have storage space.
In what way? Can you figure what is trying to refer to them?
Am I supposed to declare storage space for these constants, or is it
legal here to assume they will become compile-time constnats? What
does the C++ standard say?
Since their address is never taken, the ''foo::A'' and ''foo::B'' are, in
fact, compile-time constant expressions that do not require storage.
The objects, therefore, don''t need to be defined outside of the class
definition. g++ 3.3.3 is probably too old. It''s even too old and non-
compliant in this particular case even with 1998 version of the C++
Standard. The standard was amended to allow const statics to be only
defined in the class definition if their address is not taken _even_
if they are "used" outside the class. [I am too lazy, though, to look
it up in the Standard...]
V
Victor Bazarov wrote:John Ratliff wrote:I''m trying to find out whether g++ has a bug or not. Wait, don''t
leave, it''s a standard C++ question, I promise.
This program will compile and link fine under mingw/g++ 3.4.2, but
fails to link under Linux/g++ 3.3.3.
---------------------------------------------
#include <iostream>
#include <utility>
class foo {
private:
char sram[0x2000];
public:
static const int A = 0x8;
static const int B = 0x1FF8;
foo() {
sram[8] = 1;
sram[9] = 2;
sram[0x1FF8] = 3;
sram[0x1FF9] = 4;
}
std::pair<unsigned char, unsigned char> method(bool redundant)
const { int offset = (redundant ? B : A);
return std::pair<unsigned char,
unsigned char>(sram[offset], sram[offset +
1]); }
};
int main(int, char **) {
foo f;
std::pair<unsigned char, unsigned char> p1(f.method(false));
std::pair<unsigned char, unsigned char> p2(f.method(true));
std::cout << "p1 = (" << (int)p1.first << ","
<< (int)p1.second << ")\n";
std::cout << "p2 = (" << (int)p2.first << ","
<< (int)p2.second << ")\n";
return 0;
}
---------------------------------------------
The program is well-formed. ''A'' and ''B'' are never used outside of
the class definition, so they don''t need to be defined. That''s what
1998 version of the Standard used to say. It was changed a bit in the
2003 version (IIRC) but to give programmers even more leeway.The reason is that in mingw/g++ 3.4.2, the static constants A and B
are replaced during compile time and didn''t need storage space. The
linker therefore didn''t need to find them. However, Linux/g++ 3.3.3
generates code that requires them to have storage space.
In what way? Can you figure what is trying to refer to them?
This is the assembly generated from Linux/g++ 3.3.3 for foo::method when
using g++ -S temp.cc. No extra optimization declared, though it doesn''t
fix it if you do -O2. The really stupid thing is that if you replace the
ternary operator with an if statement, it will treat A and B as
compile-time constants properly.
-----------------------------------------------------
_ZNK3foo6methodEb:
..LFB1535:
pushl %ebp
..LCFI14:
movl %esp, %ebp
..LCFI15:
subl
24, %esp
..LCFI16:
movl 16(%ebp), %eax
movb %al, -1(%ebp) ; stick redundant on the stack
cmpb
这篇关于关于静态常量的c ++标准的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!