What does {0} mean when initializing an object?

后端 未结 10 742
-上瘾入骨i
-上瘾入骨i 2020-11-29 14:46

When {0} is used to initialize an object, what does it mean? I can\'t find any references to {0} anywhere, and because of the curly braces Google s

相关标签:
10条回答
  • 2020-11-29 15:31

    In answer to why ShellExecuteEx() is crashing: your SHELLEXECUTEINFO "sexi" struct has many members and you're only initializing some of them.

    For example, the member sexi.lpDirectory could be pointing anywhere, but ShellExecuteEx() will still try to use it, hence you'll get a memory access violation.

    When you include the line:

    SHELLEXECUTEINFO sexi = {0};
    

    before the rest of your structure setup, you're telling the compiler to zero out all structure members before you initialize the specific ones you're interested in. ShellExecuteEx() knows that if sexi.lpDirectory is zero, it should ignore it.

    0 讨论(0)
  • 2020-11-29 15:32

    I have always wondered, why you should use something like

    struct foo bar = { 0 };
    

    Here is a test case to explain:

    check.c

    struct f {
        int x;
        char a;
    } my_zero_struct;
    
    int main(void)
    {
        return my_zero_struct.x;
    }
    

    I compile with gcc -O2 -o check check.c and then output the symbol table with readelf -s check | sort -k 2 (this is with gcc 4.6.3 on ubuntu 12.04.2 on a x64 system). Excerpt:

    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
    

    The important part here is, that my_zero_struct is after __bss_start. The ".bss" section in a C program is the section of memory which is set to zero before main is called see wikipedia on .bss.

    If you change the code above to:

    } my_zero_struct = { 0 };
    

    Then the resulting "check" executable looks exactly the same at least with the gcc 4.6.3 compiler on ubuntu 12.04.2; the my_zero_struct is still in the .bss section and thus it will be automatically initialized to zero, before main is called.

    Hints in the comments, that a memset might initialize the "full" structure is also not an improvement, because the .bss section is cleared fully which also means the "full" structure is set to zero.

    It might be that the C language standard does not mention any of this, but in a real world C compiler I have never seen a different behaviour.

    0 讨论(0)
  • 2020-11-29 15:35

    Note that an empty aggregate initializer also works:

    SHELLEXECUTEINFO sexi = {};
    char mytext[100] = {};
    
    0 讨论(0)
  • 2020-11-29 15:41

    What's happening here is called aggregate initialization. Here is the (abbreviated) definition of an aggregate from section 8.5.1 of the ISO spec:

    An aggregate is an array or a class with no user-declared constructors, no private or protected non-static data members, no base classes, and no virtual functions.

    Now, using {0} to initialize an aggregate like this is basically a trick to 0 the entire thing. This is because when using aggregate initialization you don't have to specify all the members and the spec requires that all unspecified members be default initialized, which means set to 0 for simple types.

    Here is the relevant quote from the spec:

    If there are fewer initializers in the list than there are members in the aggregate, then each member not explicitly initialized shall be default-initialized. Example:

    struct S { int a; char* b; int c; };
    S ss = { 1, "asdf" };
    

    initializes ss.a with 1, ss.b with "asdf", and ss.c with the value of an expression of the form int(), that is, 0.

    You can find the complete spec on this topic here

    0 讨论(0)
提交回复
热议问题