问题描述
我最近遇到了这个问题,但无法弄清楚为什么该语言允许b = c;并失败b = {3,4}。允许后者存在问题吗?
I encountered this recently but could not figure out why the language would allow b = c; below and fail b = {3, 4}. Is there an issue with allowing the latter ?
struct T {
int x;
int y;
};
int main()
{
T a = {1, 2};
T b;
b = {3, 4}; // why does this fail ?
T c = {3, 4};
b = c; // this works
return 0;
}
推荐答案
由于 {3,4}
虽然是有效的初始化程序,但它不是表达式(至少它不在C中;有关C ++的更多信息,请参见下文)。
It fails because {3, 4}
, though it's a valid initializer, is not an expression (at least it isn't in C; see below for more about C++).
C中的每个表达式的类型都可以通过检查表达式本身来确定。 {3,4}
的类型可能为 struct T
或 int [2]
(数组类型)或无数其他类型。
Every expression in C has a type that can be determined by examining the expression itself. {3, 4}
could potentially be of type struct T
, or int[2]
(an array type), or any of a myriad of other types.
C99添加了一个名为 compoundliteral 的新功能。 em>使用与初始化程序类似的语法,但是让您指定类型并创建一个表达式:
C99 added a new feature called compound literals that use a similar syntax to initializers, but let you specify the type, creating an expression:
b = (struct T){3, 4};
请注意,(结构T)
为 not 强制转换运算符;
Note that the (struct T)
is not a cast operator; it's part of the syntax of a compound literal.
有关复合文字的更多信息,请参见。
For more information on compound literals, see section 6.5.2.5 of the draft C11 standard.
1999 ISO C标准(C99)。如果您的编译器不支持C99或更高版本(*咳嗽*微软*咳嗽*),那么您将无法使用它们。
Compound literals were introduced by the 1999 ISO C standard (C99). If your compiler doesn't support C99 or better (*cough*Microsoft*cough*), then you won't be able to use them.
如果使用C ++(别忘了,这是另一种语言),它不支持复合文字,但是可能有替代方法。正如Potatoswatter在评论中指出的那样:
If you're using C++ (which, don't forget, is a different language), it doesn't support compound literals, but there may be an alternative. As Potatoswatter points out in a comment, this:
b = T{3, 4};
在C ++ 11中有效(但在C ++语言的早期版本中无效)。 C ++标准的第5.2.3节[expr.type.conf]中对此进行了介绍。
is valid in C++11 (but not in earlier versions of the C++ language). This is covered in section 5.2.3 [expr.type.conf] of the C++ standard.
为此,
b = {3, 4};
也是有效的C ++ 11语法。此表格可以在许多指定的上下文中使用,包括作业的右侧。 C ++标准的8.5.4节[dcl.init.list]中对此进行了介绍。
is also valid C++11 syntax. This form can be used in a number of specified contexts, including the right side of an assignment. This is covered in section 8.5.4 [dcl.init.list] of the C++ standard.
C ++标准的最新草案是N3485。
One recent draft of the C++ standard is N3485.
(g ++在C ++中支持C99风格的复合文字作为扩展。)
(g++ supports C99-style compound literals in C++ as an extension.)
C99编译器,您始终可以编写自己的初始化函数,例如:
And if you're stuck with a pre-C99 compiler, you can always write your own initialization function, such as:
struct T init_T(int x, int y) {
struct T result;
result.x = x;
result.y = y;
return result;
}
/* ... */
struct T obj;
/* ... */
obj = init_T(3, 4);
这是一个烦人的额外工作(这就是C99添加复合文字的原因),但是它确实工作。另一方面,在大多数情况下,使用初始化可能会更好:
It's an annoying amount of extra work (which is why C99 added compound literals), but it does the job. On the other hand, in most cases you're probably better off using initialization:
struct T obj;
/* ... */
{
struct T tmp = { 3, 4 };
obj = tmp;
}
哪个更好取决于程序的结构。
Which is better probably depends on how your program is structured.
这篇关于C:声明后初始化结构变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!