当{0}用于初始化一个对象时,它意味着什么?我在任何地方都找不到{0}的任何引用,而且由于花括号,谷歌的搜索没有帮助。

示例代码:

SHELLEXECUTEINFO sexi = {0}; // what does this do?
sexi.cbSize = sizeof(SHELLEXECUTEINFO);
sexi.hwnd = NULL;
sexi.fMask = SEE_MASK_NOCLOSEPROCESS;
sexi.lpFile = lpFile.c_str();
sexi.lpParameters = args;
sexi.nShow = nShow;

if(ShellExecuteEx(&sexi))
{
    DWORD wait = WaitForSingleObject(sexi.hProcess, INFINITE);
    if(wait == WAIT_OBJECT_0)
        GetExitCodeProcess(sexi.hProcess, &returnCode);
}

如果没有它,上面的代码将在运行时崩溃。


当前回答

我已经有一段时间没有在c/c++中工作了,但是IIRC,同样的快捷方式也可以用于数组。

其他回答

关于ShellExecuteEx()崩溃的原因:你的SHELLEXECUTEINFO "sexi"结构体有很多成员,你只初始化了其中的一些成员。

例如,sexi成员。lpDirectory可以指向任何地方,但ShellExecuteEx()仍将尝试使用它,因此您将得到内存访问冲突。

当你包括这行:

SHELLEXECUTEINFO sexi = {0};

在结构设置的其余部分之前,您告诉编译器在初始化您感兴趣的特定结构成员之前将所有结构成员归零。ShellExecuteEx()知道如果sexi。lpDirectory是0,它应该忽略它。

我一直在想,为什么你要用

struct foo bar = { 0 };

下面是一个要解释的测试用例:

check.c

struct f {
    int x;
    char a;
} my_zero_struct;

int main(void)
{
    return my_zero_struct.x;
}

我用gcc -O2 -o check check.c编译,然后用readelf -s check | sort -k 2输出符号表(这是在x64系统上的ubuntu 12.04.2上的gcc 4.6.3)。摘录:

59: 0000000000601018     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
48: 0000000000601018     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
25: 0000000000601018     0 SECTION LOCAL  DEFAULT   25 
33: 0000000000601018     1 OBJECT  LOCAL  DEFAULT   25 completed.6531
34: 0000000000601020     8 OBJECT  LOCAL  DEFAULT   25 dtor_idx.6533
62: 0000000000601028     8 OBJECT  GLOBAL DEFAULT   25 my_zero_struct
57: 0000000000601030     0 NOTYPE  GLOBAL DEFAULT  ABS _end

这里重要的部分是,my_zero_struct位于__bss_start之后。”。在C程序中,section是内存中在main被调用之前被设置为0的部分。

如果你将上面的代码更改为:

} my_zero_struct = { 0 };

然后产生的“check”可执行文件看起来至少与gcc 4.6.3编译器在ubuntu 12.04.2上完全相同;my_zero_struct仍然在.bss节中,因此在main被调用之前,它将被自动初始化为零。

注释中的提示,memset可能初始化“full”结构也不是一个改进,因为.bss部分被完全清除,这也意味着“full”结构被设置为零。

C语言标准可能没有提到这一点,但在现实世界的C编译器中,我从未见过不同的行为。

需要注意的一件事是,这种技术不会将填充字节设置为零。例如:

struct foo
{
    char c;
    int  i;
};

foo a = {0};

并不等同于:

foo a;
memset(&a,0,sizeof(a));

在第一种情况下,c和i之间的pad字节是未初始化的。你为什么关心这个?好吧,如果你把数据保存到磁盘上或者通过网络发送,你可能会有安全问题。

它是将整个结构初始化为空/零/空值的语法糖。

长版本

SHELLEXECUTEINFO sexi;
sexi.cbSize = 0;
sexi.fMask = 0;
sexi.hwnd = NULL;
sexi.lpVerb = NULL;
sexi.lpFile = NULL;
sexi.lpParameters = NULL;
sexi.lpDirectory = NULL;
sexi.nShow = nShow;
sexi.hInstApp = 0;
sexi.lpIDList = NULL;
sexi.lpClass = NULL;
sexi.hkeyClass = 0;
sexi.dwHotKey = 0;
sexi.hMonitor = 0;
sexi.hProcess = 0;

短的版本

SHELLEXECUTEINFO sexi = {0};

那不是简单多了吗?

这也很好,因为:

你不需要找到每个成员并初始化它 您不必担心在稍后添加新成员时可能无法初始化 你不需要调用零内存

我已经有一段时间没有在c/c++中工作了,但是IIRC,同样的快捷方式也可以用于数组。