在C99(而不是C++)中,可以使用以下语法初始化结构:
struct info
{
char name[8+1];
int sz;
int typ;
};
struct info arr[] =
{
[0] = { .sz = 20, .name = "abc" },
[9] = { .sz = -1, .name = "" }
};
Run Code Online (Sandbox Code Playgroud)
未指定的字段会发生什么?
我知道在C99中你可以使用成员名称初始化结构的成员,如下所示:
struct myStruct
{
int i;
char c;
float f;
};
Run Code Online (Sandbox Code Playgroud)
以下是有效的:
struct myStruct m = {.f = 10.11, .i = 5, .c = 'a'};
Run Code Online (Sandbox Code Playgroud)
还有人说,未初始化的成员将被设置为0.所以
struct myStruct m = {.f = 10.11, .c = 'a'};
Run Code Online (Sandbox Code Playgroud)
这里i将设置为0
但是,对于以下内容:
struct myStruct m = {.f = 10.11, .c = 'a', 6};
Run Code Online (Sandbox Code Playgroud)
i 仍然初始化为0.如果我们进行这样的复合初始化是什么原因.
是否有任何具体原因为什么没有将指定的初始值设定项添加到g ++?是因为C99标准迟到了,而g ++是早期开发的,之后人们不关心这个问题,或者在C++语法中实现指定的初始化器存在一些固有的困难?
使用VS2013 Update 2,我偶然发现了一些奇怪的错误消息:
// test.c
int main(void)
{
struct foo {
int i;
float f;
};
struct bar {
unsigned u;
struct foo foo;
double d;
};
struct foo some_foo = {
.i = 1,
.f = 2.0
};
struct bar some_bar = {
.u = 3,
// error C2440 : 'initializing' : cannot convert from 'foo' to 'int'
.foo = some_foo,
.d = 4.0
};
// Works fine
some_bar.foo = some_foo;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC和Clang都接受了.
我错过了什么或这段代码是否暴露了编译器错误?
c designated-initializer compiler-bug visual-studio-2013 msvc12
我正在尝试创建一个简单的UIBarButtonItem的Swift子类:
class LabelBarButtonItem: UIBarButtonItem {
let label: UILabel
init(text: String) {
self.label = UILabel(frame: CGRectZero)
self.label.tintColor = UIColor.grayColor()
super.init(customView: self.label)
self.label.text = text
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我尝试实例化这个:
let countButton = LabelBarButtonItem(text: "0 items")
Run Code Online (Sandbox Code Playgroud)
代码编译正确但在运行时失败:
fatal error: use of unimplemented initializer 'init()' for class 'TestProject.LabelBarButtonItem'
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么在这种情况下会发生这种情况,或者一般来说是什么原则导致这个问题.在init(text)初始化应直接委托给init(customView)超类.为什么要init()打电话?它不应该涉及.
任何人都可以解释发生了什么吗?当我试图继承其他UIKit类时,会出现类似的问题
我正在创建自己的自定义tableViewCell然后我得到一个错误说:
'required'initulator'init(coder :)'必须由'UITableViewCell'的子类提供
我查了一下,显然这也是实现它的必要条件.但这导致我对必需与指定初始化器的混淆
必需的初始化器:
在定义类初始值设定项之前编写必需的修饰符,以指示该类的每个子类都必须实现该初始化程序:
指定的初始化程序
指定的初始值设定项是类的主要初始值设定项.指定的初始化程序完全初始化该类引入的所有属性,并调用适当的超类初始化程序以继续超类链的初始化过程.
以下陈述是否正确:
话虽如此,我仍然不完全理解他们的功能差异.
有一段时间了,人们已经能够在GCC中使用"指定的初始化程序":
struct CC{
double a_;
double b_;
};
CC cc{.a_ = 1., .b_ = 2.}; assert(cc.a_ == 1. and cc.b_ == 2.); // ok
CC cc{.bla = 0., .bli = 0.}; // compile error
Run Code Online (Sandbox Code Playgroud)
但是,当我添加构造函数时,标签将被忽略.
struct CC{
double a_;
double b_;
CC(double a, double b) : a_{a}, b_{b}{}
};
CC cc{.a_ = 1., .b_ = 2.}; assert(cc.a_ == 1. and cc.b_ == 2.); // ok
CC cc{.b_ = 2., .a_ = 1.}; // compiles but labels don't matter only the …Run Code Online (Sandbox Code Playgroud) 我遇到了以下迷宫定义代码:
typedef struct mazeNode {
int hasCheese;
int tag;
struct mazeNode *left;
struct mazeNode *right;
} maze_t;
maze_t maze = {
.tag = 1,
.left = &(maze_t) {
.left = &(maze_t) {
.left = &(maze_t) {},
.right = &(maze_t) {}
},
.right = &(maze_t) {
.right = &(maze_t) {}
}
},
.right = &(maze_t) {
.tag = 8,
.left = &(maze_t) {},
.right = &(maze_t) {
.tag = 10,
.left = &(maze_t) {
.tag = 11,
.left = …Run Code Online (Sandbox Code Playgroud) 在这里,我已经初始化了这样的数组:
#include <stdio.h>
int main()
{
int a[10] = {1, 2, 3, [7] = 4, 8, 9};
printf("a[7] = %d\na[8] = %d\na[9] = %d\n", a[7], a[8], a[9]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
a[7] = 4
a[8] = 8
a[9] = 9
Run Code Online (Sandbox Code Playgroud)
在这里,我选择了数组索引7作为a a[7] = 4,然后添加了一些元素.然后打印索引的数组元素7,8并9正确打印.
那么,索引的输出是否正确8而9没有明确定义呢?为什么序列不是从索引开始的3?
c arrays initialization designated-initializer initializer-list
考虑以下代码:
struct Foo{
std::string s1;
std::string s2;
};
int main(){
Foo f{.s1 = "s1", .s2 = f.s1 + "s2"};
std::cout << "s1='" << f.s1 << "', s2='" << f.s2 << "'" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
特别注意 的初始化访问:s2的第一个成员。最新的 clang、gcc 和 MSVC 对代码很满意,并给出了天真的预期结果(它们打印)。观看Godbolt直播。f.s2 = f.s1 + "s2""s1='s1', s2='s1s2'"
问题:这合法吗?换句话说,标准是否保证在f.s1指定的初始化器被.s2评估之前被初始化?
相关:有一个类似的问题询问是否.s2 = .s1 + "s2"合法,这显然是不合法的,因为它无法编译。另外,P0328(根据此答案)可能相关,但我看不到我的问题在那里得到解答。
c++ designated-initializer language-lawyer aggregate-initialization c++20
c ×6
c++ ×3
c++20 ×2
swift ×2
arrays ×1
c99 ×1
compiler-bug ×1
g++ ×1
gcc ×1
initializer ×1
linux ×1
msvc12 ×1
objective-c ×1
struct ×1
structure ×1