LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   GCC giving warning - braces around initializers (https://www.linuxquestions.org/questions/programming-9/gcc-giving-warning-braces-around-initializers-587680/)

fcdev 09-27-2007 02:42 AM

GCC giving warning - braces around initializers
 
I'm porting some code from Windows (compiled under MSVC) to Linux and OSX using GCC/G++ as the compiler ... well, reconfiguring the source to be cross-platform. Anyway, the source code compiles with no warnings under MSVC, but G++ doesn't like one of the initializers.

The warning appears in the initialization of the sLight light[] array.
This is a 3D graphics application, and float4 (used very heavily in this source code) is a structure holding 4 floats which could represent a position (x,y,z,w) or a color (r,g,b,a). The position and color values must overlap, such that x==r, y==g, z==b, w==a.

struct float4
{
union
{
struct
{ float x,y,z,w;
};
struct
{ float r,g,b,a;
};
};
};

struct sLight
{ float4 position, color;
};

sLight light[2] =
{
{ // Light 0
{1.0, 0.0, 0.0, 32}, // Position
{1.0, 0.0, 0.0, 1.0} }, // Color
{ // Light 1
{-1.0, 0.0, 0.0, 128}, // Position
{0.0, 0.0, 0.5, 1.0} } // Color
};


This code produces no warnings under MSVC, but GCC is reporting
Warning: Missing Braces around initializer for 'float4::<anonymous union>'

Does anyone have any suggestions for how to properly initialize this array without generating warnings?
(by the way, the code does compile and run correctly, but I prefer to have absolutely no warnings in the code).

Thanks,
Stephen Fraser

Hko 09-27-2007 06:55 AM

The members of struct sLight (postion and color) are structs which has a union of two structs inside. That is a 3-levels nesting. So you need 3 curly braces around the initialization of postion and color.

Also, my compiler reported errors for missing struct keywords (gcc 4.2.1 with -Wall option).

Fixed code:
Code:

struct float4
{

    union
    {

        struct
        { float x,y,z,w;
        };
        struct
        { float r,g,b,a;
        };

    };

};

struct sLight
{ struct float4 position, color;
};

struct sLight light[2] =
{

    { // Light 0

        {{ {1.0, 0.0, 0.0, 32} }}, // Position
        {{ {1.0, 0.0, 0.0, 1.0} }} }, // Color

    { // Light 1

        {{ {-1.0, 0.0, 0.0, 128} }}, // Position
        {{ {0.0, 0.0, 0.5, 1.0} }} } // Color

};


fcdev 09-27-2007 07:07 AM

Thanks, that got rid of the warning, gave the same correct result in execution, and even compiled under MSVC ... perfect!

As for the missing 'struct' keywords, they're not needed when compiling a C++ program within G++, even when using -Wall.

Once again, thank you ... perfect result.

dmail 09-27-2007 11:28 AM

I am confused, G++ should give an error about the following code
Code:

struct float4
{

    union
    {

        struct
        { float x,y,z,w;
        };
        struct
        { float r,g,b,a;
        };

    };

};

It is not standard C++ if I remember correctly, a union can be anonymous but it can not create new types which this does. I will look for the specific part of the standard.

Quote:

9.5.2
A union of the form
union { member-specification } ;
is called an anonymous union; it defines an unnamed object of unnamed type. The member-specification of an anonymous
union shall only define non-static data members. [ Note: nested types and functions cannot be declared within an
anonymous union. —end note ]
MSVC uses a language extension I was not aware the G++ also has this extension.

fcdev 09-28-2007 01:21 AM

Quote:

Originally Posted by dmail (Post 2905569)
It is not standard C++ if I remember correctly, a union can be anonymous but it can not create new types which this does. I will look for the specific part of the standard.

...

MSVC uses a language extension I was not aware the G++ also has this extension.

Yeah, it didn't look right to me either, but it appeared to work, so I left it at that. I suppose the same thing could probably be achieved with a structure like this (or something like it) ...

struct float4
{
union {float x, r;};
union (float y, g;};
union (float z, b;};
union (float w, a;};
};

I'm probably going to try converting the structure to this, since the solution above worked great on Linux & Windows, but didn't work on OSX (even though OSX uses GCC/G++, but maybe I need to find the compiler flags within Xcode, and set them to match the ones in Linux).

The objective is that when assigning values, you can say ...
r = 0.0f;
x = 10.0f;
printf("%.2f",r);

and you get "10.00" (r = 10.0).

It's really handy when working in vertex and fragment shaders, and you don't want to differentiate between position/vector, and color data, but at the same time, don't want to have a situation where you're constantly asking yourself ... "Is the Green component stored in Y, or Z?".


All times are GMT -5. The time now is 10:02 AM.