Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of struct identifier to signify POD types and C structures

Consider the following piece of code:

struct Foo {};

template<typename ForwardIterator>
struct Foo*
Bar(ForwardIterator first, ForwardIterator last)
{ 
    (void)first;
    (void)last;
    Foo *foo(nullptr);
    return foo;
}

The above piece of code compiles fine in Clangv3.5 and GCCv4.9.

However, it fails to compile in VC++2013.

Removing the struct identifier (see below) from the return type solves the problem:

struct Foo {};

template<typename ForwardIterator>
Foo*
Bar(ForwardIterator first, ForwardIterator last)
{ 
    (void)first;
    (void)last;
    Foo *foo(nullptr);
    return foo;
}

Q1:

Is this a visual studio bug?

Q2:

This issue came up, because in my code-base the Foo struct lies in a .h.c file (i.e., is a C struct) and in order to signify C/POD structs in my code, I use the struct identifier. Is this a bad idea (i.e., in C++ code I should avoid to use struct identifier in this fashion)?

like image 452
101010 Avatar asked Nov 05 '14 10:11

101010


People also ask

Is a struct a POD?

To be more clear, a POD is what we call "a struct": a unit or a group of units that just store data.

What is a POD struct C++?

A Plain Old Data (POD) structure is an aggregate class that contains only PODs as members. It doesn't have any user-defined constructors or destructors. There are also no non-static members of the pointer-to-member type in it. A POD structure is a struct or class which only has member variables.

What are POD types?

A POD type is a C++ type that has an equivalent in C, and that uses the same rules as C uses for initialization, copying, layout, and addressing. As an example, the C declaration struct Fred x; does not initialize the members of the Fred variable x.


1 Answers

The main point of an elaborated type specifiers is to allow you refer to a name that has been hidden, from the draft C++ standard section 3.4.4 Elaborated type specifiers:

An elaborated-type-specifier (7.1.6.3) may be used to refer to a previously declared class-name or enum-name even though the name has been hidden by a non-type declaration (3.3.10).

and so in the case where Foo is hidden, you would have to use an elaborated type specifiers:

struct Foo {};

void Foo()
{
}

I see nothing in 7.1.6.3 Elaborated type specifiers or 14 Templates that would prevent this use. In fact it looks like from the description of CS2989 Visual Studio is getting confused and thinks you are attempting to redefine a non-template class as a template class.

So this looks like a bug to me, so I would file a bug report.

Update

Filed a bug report.

like image 171
Shafik Yaghmour Avatar answered Oct 04 '22 20:10

Shafik Yaghmour