10

The following code compiles in C++

struct foo
{
    int a, b;
};

struct foo foo()
{
    struct foo a;
    return a;
}

int main(void) {
    foo();
    return 0;
}
  1. Is it supposed to be allowed to have a struct and a function with the same name ?
  2. Since it compiles I then go on and try to declare an object of type foo. Is there a way? It seems impossible to do :

    foo a;   // error: expected ‘;’ before ‘a’
    foo a{}; // error: expected ‘;’ before ‘a’
    foo a(); // most vexing parse would kick in any way
    
2

5 Answers 5

10

Yes, this is allowed we can see this by going to draft C++ standard section 3.3.10 Name hiding paragraph 2 and it says (emphasis mine):

A class name (9.1) or enumeration name (7.2) can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope. If a class or enumeration name and a variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.

In this case using struct in the declaration would fix your issue:

struct foo a;
Sign up to request clarification or add additional context in comments.

Comments

2

Just do it like you would in C, using:

struct foo a;

You might even initialise it like this:

struct foo a{};
struct foo a = {0};

A workaround would be using a typedef, thus avoiding any ambiguity and other difficulties:

typedef struct foo s_foo;

3 Comments

I think that a clever typedef would actually make things less complicated and more readable.
@Jefffrey: Is that a criticism of the chosen name, or something deeper? Because atm I cannot see how it can be anything else but the first, so I think there must be something I overlook. Care to clarify?
"Still, it complicates things unneccessarily." -- A clever use of a typedef could make things less complicated and more readable.
1

Usually a bad habbit to do something like that. I would name it foo_s or whatever to distinguish it from the function. Other than that, there isn't really a way of doing it.

In C this is possible, since it requires

struct foo

instead of just

foo

as the type name (unless it is typedef'd)

Comments

1

Yes, you can, but it's a really bad pattern to get into.

struct foo
{
};

foo foo(foo& f)
{
    return f;
}

int main()
{
    struct foo f;
    foo(f);
    return 0;
}

See livedemo: http://ideone.com/kRK19f

The trick was to specify struct foo when we wanted to get at the type. Note that, until you create this ambiguity, it's actually not necessary to keep saying struct, this isn't C (as in the line foo foo(foo& f)).

Most developers choose a camel casing pattern, e.g they use an upper case letter to distinguish type names and a lowercase letter for a function name:

struct Foo
{
};

Foo foo(); // no ambiguity.

Back in Microsoft's prime, many Windows developers acquired the habit of prefixing struct/class definitions, the definition of a class of thing if you will, with a capital C

struct CFoo
{
};

Now, even if you want to use upper-case first letters for your function names, there is no ambiguity.

Comments

1

From The.C++.Programming.Language.Special.Edition $A.8:

To preserve C compatibility, a class and a non-class of the same name can be declared in the same scope ($5.7). For example:

struct stat { /* ... */ };
int stat(char * name, struct stat * buf);

In this case, the plain name (stat) is the name of the non-class. The class must be referred to using a class-key prefix .

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.