1

How can I typedef a struct but still keep the new type namespaced under the keyword 'struct'?

example:

struct foo {
    int x; 
}; 

typedef struct foo struct bar; 


int main(void) {
    struct bar bar; 
    bar.x = 10; 

    return 0; 
}

but this doesn't work obviously. Here are the errors if anyone is curious:

main.c:5:20: error: two or more data types in declaration specifiers
 typedef struct foo struct bar;
                    ^
main.c:5:27: warning: useless storage class specifier in empty declaration
 typedef struct foo struct bar;
                           ^
main.c: In function 'main':
main.c:9:13: error: storage size of 'bar' isn't known
  struct bar bar;
  • 2
    What exactly do you want that typedef to do? Just remove it. This code would work just fine if you removed the typedef line. – klutt Jul 23 '20 at 19:05
  • 1
    If you still want to use `struct` then just don't typedef. – stark Jul 23 '20 at 19:06
  • I don't know, I was just showing an example that kind of shows what I am trying to do. Not saying typedef is necessarily the correct solution. –  Jul 23 '20 at 19:07
  • _Why_ are you trying to do it? What is your wider goal? – Asteroids With Wings Jul 23 '20 at 19:10
  • @AsteroidsWithWings as the question states, define a new type, with a new name, but still keep it namespaced under the keyword 'struct' –  Jul 23 '20 at 19:15
  • @klutt no, it wouldn't, because `bar` would be an unknown type. –  Jul 23 '20 at 19:17
  • 3
    `#define foo bar` – user3386109 Jul 23 '20 at 19:18
  • @topoly No, that's _how_ you've decided to do it. By the way, `typedef` does not "define a new type" (though I've just realised it kind of sounds like it should). – Asteroids With Wings Jul 23 '20 at 19:19
  • @user3386109 macros don't respect scope and aren't compile time (also that is backwards) –  Jul 23 '20 at 19:20
  • 1
    @topoly I guess I'm not being clear. What is your goal, what computer program are you trying to make, that you wanted to do it by creating a type with `struct` in the name? Why did you come to that desire? What does it solve for you? What is its purpose? Put another way, why can't you just remove the `struct`? – Asteroids With Wings Jul 23 '20 at 19:23
  • @AsteroidsWithWings because I like having structs namespaced under the 'struct' –  Jul 23 '20 at 19:24
  • What @AsteroidsWithWings says. Either write `typedef struct foo bar` or use `struct foo bar` in the main function – klutt Jul 23 '20 at 19:24
  • 2
    Or in other words, why not just use `struct foo` directly instead of `struct bar`? What do you want to achieve by calling it bar instead of foo? – klutt Jul 23 '20 at 19:26
  • @klutt this is like asking why have the `typedef` keyword at all –  Jul 23 '20 at 19:27
  • @topoly The reason for the `typedef` keyword is to simplify type designators, i.e. to remove the `struct` keyword from declarations. – user3386109 Jul 23 '20 at 19:29
  • @topoly I would not say it is, because `typedef` is something that is misused quite a lot. For some problems, using a typedef is a good solution. For others it is not. – klutt Jul 23 '20 at 19:30
  • @user3386109 yes but I do not want to remove the `struct` keyword from declarations. –  Jul 23 '20 at 19:30
  • 2
    @topoly Right, so `typedef` clearly won't work for you. And the only other option is a `#define`, which you've also rejected. Hence, the answer to your question is simply, "No, you can't do that." – user3386109 Jul 23 '20 at 19:33
  • @topoly then don’t use typedef, seriously... – Fredrik Jul 23 '20 at 19:34
  • 1
    @user3386109 alright, that's all I needed to know. Thanks. –  Jul 23 '20 at 19:37

5 Answers5

3

How can I typedef a struct but still keep the new type namespaced under the keyword 'struct'?.

You cannot. A namespace is a declarative region that provides a scope to the identifiers (names of the types, function, variables etc) inside it. The concept of Namespace as it is defined within C++, is not inherent in C.

So, if you are okay with minor changes in your requirements, instead of doing something unnatural, use a simple typedef:

Instead of this:

struct foo {
    int x; 
};  

do this:

typedef struct {
    int x; 
}foo;  

Then this will work:

typedef foo bar;

int main(void )
{   
    bar b;  
  
    b.x = 10;
    return 0;  
}

Note: Although namespaces are not inherent in in C, as they are in C++, there are some interpretations eg: as discussed here, that argue the point.

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • 1
    Your assertion that using `_t` is idiomatic is suspect. The coding guidelines you link in apparent support do use that convention in one example, but they are just one set of guidelines among many, and they do not in any case express use of the `_t` convention as one of their actual guidelines. On the other hand, POSIX reserves identifiers ending in `_t`, which is a good reason to avoid using such identifiers in your own code. – John Bollinger Jul 23 '20 at 19:58
  • @JohnBollinger - I will be happy to dilute the word _idiomatic_ with _common_. Or would you recommend a different approach here? – ryyker Jul 23 '20 at 20:00
  • @JohnBollinger - after having read the _rest_ of your comment, I agree. It does conflict with `POSIX`, therefore edited the whole `_t` out. Thanks. – ryyker Jul 23 '20 at 20:03
  • 1
    @rykker ... nevertheless the _coding rules_ of every company I've worked for (embedded sw) specified the `_t` rule (`_s` for structs before typedefs and `_e` for the enums). I upvote for the intention (though not directly answering to a little surreal question). – Roberto Caboni Jul 23 '20 at 20:19
  • 1
    @RobertoCaboni - thanks. I've run into this before. On this site I have to remember there are developers who truly need to comply with rules like this within there communities, and for good reason. I just have to steer clear of making hard assertions when soft suggestions are sufficient. :) – ryyker Jul 23 '20 at 20:22
3

How can I typedef a struct but still keep the new type namespaced under the keyword 'struct'?

So, it seems that you want to define a structure alias for another structure type.

This is not possible with typedef as it creates a single word alias. The new alias can't be consisted of multiple white space separated words.

But you can use a single name like struct_bar with struct implemented inside of the name to show that bar is a structure.

#include <stdio.h>

struct foo {
    int x; 
}; 

typedef struct foo struct_bar;


int main(void) {
    struct_bar bar;
    bar.x = 10; 

    return 0; 
}
1

You can't. This isn't how it works.

You cannot "create" a type whose name is more than one word, nor can you refer to a type alias using the keyword struct.

The purpose of writing struct, in this context, is to refer to a struct type by a name that wasn't introduced as an alias. The keyword is there to say that that's what you want to do. But it's not part of the name; it cannot be part of the name.

Fortunately, there's no reason to need or even want this.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
  • @EricPostpischil I don't believe I claimed otherwise? I'll try to make the sentence clearer. – Asteroids With Wings Jul 23 '20 at 19:04
  • 2
    If one has two libraries which use structures with identical layout but different tags, and one wishes to be able to have them operate on the same data, it would be useful to have standard a way of telling the compiler to treat the two structures tags as synonymous. Unfortunately, the ability to write functions which can accept pointers to arbitrary structure types that have compatible layouts is a feature which was supported in 1974, and has been widely used since, but for which the Standard has yet to acknowledge. – supercat Jul 23 '20 at 19:16
  • 1
    @supercat That doesn't seem to have anything to do with this question or with this answer. – Asteroids With Wings Jul 23 '20 at 19:18
  • @AsteroidsWithWings He's suggesting an alternative way to accomplish what OP wants. – dbush Jul 23 '20 at 19:21
  • @dbush I didn't see a suggestion, only a history lesson, but okay - he could make that suggestion to the OP either in the comments under the question, or using `@topoly`... or by writing an answer. Aliasing distinct, but layout-compatible types has nothing to do with this answer. – Asteroids With Wings Jul 23 '20 at 19:21
  • I was offering a reason why someone might want such a feature--to accomplish something which was possible in pre-standard C, but which is not otherwise accommodated by the Standard. – supercat Jul 23 '20 at 19:24
  • @AsteroidsWithWings - I don't purposefully try to be obtuse. I am naturally that way. And I did not offer that suggestion with anything but good intentions. Sorry, I will remove the comment. (and this one in a few minutes.) – ryyker Jul 23 '20 at 20:18
1

C doesn't have any type of support for namespaces (at least not in the sense that C++ does).

When you create a typedef, the new type name is a single identifier, not multiple words. So struct bar can't be an alias for another type. You would have to call it bar or some other one-word name.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

I found a solution that works for cygwin:

struct foo {
    int x; 
}; 

struct bar {
    struct foo; 
};