Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The common idiom is using both: </p> <pre><code>typedef struct X { int x; } X; </code></pre> <p>They are different definitions. To make the discussion clearer I will split the sentence:</p> <pre><code>struct S { int x; }; typedef struct S S; </code></pre> <p>In the first line you are defining the identifier <code>S</code> within the struct name space (not in the C++ sense). You can use it and define variables or function arguments of the newly defined type by defining the type of the argument as <code>struct S</code>:</p> <pre><code>void f( struct S argument ); // struct is required here </code></pre> <p>The second line adds a type alias <code>S</code> in the global name space and thus allows you to just write:</p> <pre><code>void f( S argument ); // struct keyword no longer needed </code></pre> <p>Note that since both identifier name spaces are different, defining <code>S</code> both in the structs and global spaces is not an error, as it is not redefining the same identifier, but rather creating a different identifier in a different place.</p> <p>To make the difference clearer:</p> <pre><code>typedef struct S { int x; } T; void S() { } // correct //void T() {} // error: symbol T already defined as an alias to 'struct S' </code></pre> <p>You can define a function with the same name of the struct as the identifiers are kept in different spaces, but you cannot define a function with the same name as a <code>typedef</code> as those identifiers collide.</p> <p>In C++, it is slightly different as the rules to locate a symbol have changed subtly. C++ still keeps the two different identifier spaces, but unlike in C, when you only define the symbol within the class identifier space, you are not required to provide the struct/class keyword:</p> <pre><code> // C++ struct S { int x; }; // S defined as a class void f( S a ); // correct: struct is optional </code></pre> <p>What changes are the search rules, not where the identifiers are defined. The compiler will search the global identifier table and after <code>S</code> has not been found it will search for <code>S</code> within the class identifiers.</p> <p>The code presented before behaves in the same way:</p> <pre><code>typedef struct S { int x; } T; void S() {} // correct [*] //void T() {} // error: symbol T already defined as an alias to 'struct S' </code></pre> <p>After the definition of the <code>S</code> function in the second line, the struct S cannot be resolved automatically by the compiler, and to create an object or define an argument of that type you must fall back to including the <code>struct</code> keyword:</p> <pre><code>// previous code here... int main() { S(); struct S s; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload