一个关于标准转换的问题,supermegaboy等请进
原问题:http://tieba.baidu.com/p/1285092826
现在的问题是我不清楚我的解释是否完全正确。
我找过N3290全文的array-to-pointer conversion出现的地方;3.10;以及Clause 5的所有conversion和rvalue出现的地方,但没有发现ISO C++保证内建操作符在哪些确定情况下应用这些lvalue transformation。这样,按ISO C++(C++03也一样)就无法完全解决这里的问题——如何断定表达式"12"+12是合法的。
是ISO C++的defect,还是我看漏了?
[解决办法]
试试
#define TEMP(X) #X
#define COUT(X) \
cout <<"literal:\t" <<TEMP(X) <<endl; \
cout <<"type_id:\t" <<typeid(X).name() <<endl; \
cout <<"cout_val:\t" <<X <<endl; \
cout <<"size_of:\t" <<sizeof(X) <<endl; \
cout <<"- - - - -" <<endl <<endl
#define S1 "1234567890"
#define S2 "1234567890"+1
#define S3 "1234567890"+1+1
#define S4 "1234567890"+1+1+1
#define S5 "1234567890"+1+1+1+1
int main()
{
COUT(S1);
COUT(S2);
COUT(S3);
COUT(S4);
COUT(S5);
return 0;
}
vs2008结果:
literal: "1234567890"
type_id: char const [11]
cout_val: 1234567890
size_of: 11
- - - - -
literal: "1234567890"+1
type_id: char const [11]
cout_val: 234567890
size_of: 11
- - - - -
literal: "1234567890"+1+1
type_id: char const *
cout_val: 34567890
size_of: 4
- - - - -
literal: "1234567890"+1+1+1
type_id: char const *
cout_val: 4567890
size_of: 4
- - - - -
literal: "1234567890"+1+1+1+1
type_id: char const *
cout_val: 567890
size_of: 4
- - - - -
请按任意键继续. . .
[解决办法]
总结一个特点:
vs2008下
sizeof
"1234567890" 当作字符数组
"1234567890"+0 还是当作字符数组
"1234567890"+0+0 就当作字符指针了
但是改变一下结合顺序
"1234567890"+(0+0) 则仍然当作字符数组
[解决办法]
literal: "1234567890"
type_id: A11_c
cout_val: 1234567890
size_of: 11
- - - - -
literal: "1234567890"+1
type_id: PKc
cout_val: 234567890
size_of: 4
- - - - -
literal: "1234567890"+1+1
type_id: PKc
cout_val: 34567890
size_of: 4
- - - - -
literal: "1234567890"+1+1+1
type_id: PKc
cout_val: 4567890
size_of: 4
- - - - -
literal: "1234567890"+1+1+1+1
type_id: PKc
cout_val: 567890
size_of: 4
- - - - -
Process returned 0 (0x0) execution time : 0.406 s
Press any key to continue.
Code::Blocks10.5上的gcc编译的, 这个结果看上去比楼上那么的结果看上去更好理解
[解决办法]
呵呵
可见,cout 都是将 "string_literal"+num 转换为 char* + int
但是 sizeof 明显因编译器而不同
[解决办法]
从C::B的那个编译器看来, char[]+int就会转成char*
所以后面的四个都是4了
[解决办法]
编译器如果能理解"abcdef"[3];那么就理解"abcdef"+3了。
[解决办法]
>>问题是“谁合法就选谁”——不管左值之类的话,哪来的?
首先,对于内建的operator+,并未要求两个操作数是否为lvalue。更何况文字常量是一个具有外部连接的左值。
这样就回到一个问题上
char[3] + int,内建operator+明显不允许这样的操作
const char* + int,这无须质疑了。
[解决办法]
[Note: a standard conversion sequence can be empty, i.e., it can consist of no conversions. ] A standard conversion sequence will be applied to an expression if necessary to convert it to a required destination type.
2 [Note: expressions with a given type will be implicitly converted to other types in several contexts:
— When used as operands of operators. The operator’s requirements for its operands dictate the destination type (clause 5).
— When used in the condition of an if statement or iteration statement (6.4, 6.5). The destination type is bool.
— When used in the expression of a switch statement. The destination type is integral (6.4).
— When used as the source expression for an initialization (which includes use as an argument in a function call and use as the expression in a return statement). The type of the entity being initialized is
(generally) the destination type. See 8.5, 8.5.3.
—end note]