关于静态常量的c ++标准 [英] the c++ standard on static constants

查看:52
本文介绍了关于静态常量的c ++标准的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在试图找出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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆