Theres some sample code I have been working with from the book "Learning Core Audio" like so..
typedef struct MySineWavePlayer
{
AudioUnit outputUnit;
double startingFrameCount;
} MySineWavePlayer;
Why is "MySineWavePlayer" in this code twice?
This is a common question which is answered by explaining the difference between using typedef when defining a struct and not using typedef.
The common idiom is using both: typedef struct X { int x; } X;
They are different definitions. To make the discussion clearer I will split the sentence:
struct S { int x; };
typedef struct S S;
In the first line you are defining the identifier S
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 struct S
:
void f( struct S argument ); // struct is required here
The second line adds a type alias S
in the global name space and thus allows you to just write:
void f( S argument ); // struct keyword no longer needed
Note that since both identifier name spaces are different, defining S
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.
To make the difference clearer:
typedef struct S { int x; } T;
void S() {} // correct
//void T() {} // error: symbol T already defined as an alias to 'struct S'
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 typedef as those identifiers collide.
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:
// C++
struct S { int x; }; // S defined as a class
void f( S a ); // correct: struct is optional
What changes are the search rules, not where the identifiers are defined. The compiler will search the global identifier table and after S
has not been found it will search for S
within the class identifiers.
The code presented before behaves in the same way:
typedef struct S { int x; } T;
void S() {} // correct [*]
//void T() {} // error: symbol T already defined as an alias to 'struct S'
After the definition of the S
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 struct keyword:
// previous code here...
int main() {
S();
struct S s;
}
source
the first one is actually not needed in this case, the second one is for the typedef
if you write this
struct MySineWavePlayer
{
AudioUnit outputUnit;
double startingFrameCount;
};
then you need to do something like this to declare an instance of struct
struct MySineWavePlayer mySineWavePlayer;
you can then do this
typedef struct MySineWavePlayer MySineWavePlayer;
and then the declaration would become
MySineWavePlayer mySineWavePlayer;
so the original one
typedef struct MySineWavePlayer
{
AudioUnit outputUnit;
double startingFrameCount;
} MySineWavePlayer;
is a combination if these.
And you could even do the typedef
for an anonymous struct
typedef struct
{
AudioUnit outputUnit;
double startingFrameCount;
} MySineWavePlayer;
So short answer is first MySineWavePlayer
is the name of the struct
while the second is the name of the typedef
d type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With