Enum declaration in Eclipse - c++

I'm compiling a c++ project in Eclipse, Linux.
The project was compiled in Windows in the past.
I have my declaration of enums like this:
enum nameofenum:UINT32
{
one=0,
two=1
}
The result is an error in eclipse.
What is the meaning of :UINT32?
How can I switch this declaration to Linux?
Thanks!!

That looks like a strongly typed enum, which is a C++0x feature. Basically, it specifies the underlying type of the enumeration, so one and two will be UINT32s.
To compile it, you need a compiler that supports this particular part of the C++0x language. I believe GCC 4.4 and Visual C++ supports strongly typed enums to some extent.

The : UINT32 declares the underlying type of the enumeration; it means that the enumeration will be represented by a UINT32.
This is a new C++ feature that is being added in C++0x called strongly typed enumerations. Visual C++ has supported it at least since Visual C++ 2005; the version of g++ you are using may not support it.
As for how you get this working with g++, it depends. If you don't have any code that relies on a particular underlying type, then you can just remove it. If you do have code that relies on a particular underlying type, you might consider replacing uses of the enumeration type with the underlying type (i.e., use UINT32 instead of nameofenum); this isn't very nice, though.

UINT32 is unsigned 32bit integer, so your enum is representated by 4bytes int.
It depends. I dont' know exactly, but do you really need to use this enum as 32bit int? May be you just can avoid this :UINT32 declaration?

: UINT means that the underlying type of the enumeration identifiers is UINT.
It is a Microsoft extension described here. To make it compile remove : UINT.

Related

Error:C2016 C requires that a struct or union has at least one member

I am a newbie in c/c++ and faced a problem using some c project headers in c++.
I have two solutions, where #one containing mostly c files (also few cpp) and the #two only cpp files. each solution gets compiled and runs correctly with no errors.
both are on VisualStudio v.15.9.4 VC++ 2017 targeting windows SDK 10.0.17134.0.
I did copy-paste some header files form #one to #two and on compile get the error in the title.
typedef struct
{
U32 RESERVED;
SHARED_TYPE * SHARED;
struct
{
} ALIEN; <--- HERE
} TxRequest;
Error C2016 C requires that a struct or union has at least one member
Error (active) E0169 expected a declaration
searching answers mostly where about the difference of compilers but
targeting the same SDK where not both solutions using the same compiler? why in one solution it get compiled with no error and in one with error?
how should I fix it having the same empty struct. as changing it might affect other parts.
Standard C does not permit empty structs, as the error message helpfully points out. Standard C++ does allow them, since they can be useful as template metavalues and for overload resolution, among other purposes.
From the error message, it seems that you are compiling that header with the Visual Studio C compiler.
Other compilers are more lenient. Empty C structs are a long-standing GCC extension, and were frequently used, as in this example, as another form of the so-called "struct hack". In its classic form, the struct hack consisted of putting an array of length 1 (or, using gcc, length 0) as a kind of placeholder for a variable length extension. In this case, the variable length extension is presumably a single object of unspecified type, as opposed to the classic struct hack where it is an array of objects of specified type but unspecified length.
So GCC (and Clang) accept that struct declaration as valid C unless you request strict validation with -pedantic (and even then, it shows up as a warning, not an error).
In general, a union would be a better solution here. But that requires knowing the various possible extensions to TxRequest, so it might be more trouble than it's worth.

enum declaration in windows to linux

I have a C++ declaration:
enum SETTINGS:UINT32
{
a=1,
b=2,
};
what is the meaning of :UINT32?
how can I swich this declaration to linux?
Its part of the new C++0x way of declaring enums
enum <EnumTypeName> [: <Optinal-Type>] { <ValueList> };
By default an enum is represented by an integer.
The new syntax allows you to optionally define the type used to represent the enum
In this case it indicates that the enum underlying representation should be of type UINT32. What this means will depend on what the macro UINT32 has been defined to be. But it is probably an integer of at least 32 bits and is unsigned. :-)
See Bjornes description of the new enum stuff:
http://www2.research.att.com/~bs/C++0xFAQ.html#enum
Here, the :UINT32 syntax specifies the underlying enum type. However, this is not standard C++ (at least, not standard C++03) but a Visual Studio extension : g++ will probably reject it, and you should too.
See C++ Enumeration Declaration on MSDN for a description of this syntax
See this Wikipedia page regarding C++0x upcoming changes to enum declarations
EDIT As pointed in the comments by Martin York, g++ supports this syntax since version 4.4, so I guess the only issue for a Linux portage would be UINT32 being non standard.
u = unsigned
int = integer
32 = 32 bit
read this : "Uint32", "int16" and the like; are they standard c++?

Porting c++ code from unix to windows

Hi i have to port some stuff written on c++ from unix bases os to windows visual studio 2008.
The following code implements array data type with void ** - pointer to the data.
struct array
{
int id;
void **array; // store the actual data of the array
// more members
}
When i compile with g++ on Unix it's ok but when i try with MSVS 2008 I get the error - error C2461: 'array' : constructor syntax missing formal parameters. When i change the member from 'array' to something else it works, so it seems that the compiler thinks that the member name 'array' is actually the constructor of the struct array. It's obviously not a good practice to name the member like the struct but it's already written that way. Can i tell the MSVS compiler to ignore this problem or i should rename all members that are the same as the struct name.
You are dealing with a bug in GCC compiler. C++ language explicitly prohibits having data members whose name is the same as the name of the class (see 9.2/13). MS compiler is right to complain about it. Moreover, any C++ compiler is required to issue a diagnostic message in this case. Since GCC is silent even in '-ansi -pedantic -Wall' mode, it is a clear bug in GCC.
Revison: What I said above is only correct within the "classic" C++98 specification of C++ language. In the most recent specification this requirement only applies to static data members of the class. Non-static data members can now share the name with the class. I don't know whether this change is already in the official version of the revised standard though.
That means that both compilers are correct in their own way. MS compiler sticks to the "classic" C++98 specification of the language, while GCC seems to implement a more recent one.
I'd say that if you're doing something that you yourself describe as "not a good practice", then you should change it.
I would rename your attribute to not have the same name as the class. This will make your code more portable. If you have to move to yet another compiler in the future, you won't run in to this problem again then.

Best Practices: Should I create a typedef for byte in C or C++?

Do you prefer to see something like t_byte* (with typedef unsigned char t_byte) or unsigned char* in code?
I'm leaning towards t_byte in my own libraries, but have never worked on a large project where this approach was taken, and am wondering about pitfalls.
If you're using C99 or newer, you should use stdint.h for this. uint8_t, in this case.
C++ didn't get this header until C++11, calling it cstdint. Old versions of Visual C++ didn't let you use C99's stdint.h in C++ code, but pretty much every other C++98 compiler did, so you may have that option even when using old compilers.
As with so many other things, Boost papers over this difference in boost/integer.hpp, providing things like uint8_t if your compiler's standard C++ library doesn't.
I suggest that if your compiler supports it use the C99 <stdint.h> header types such as uint8_t and int8_t.
If your compiler does not support it, create one. Here's an example for VC++, older versions of which do not have stdint.h. GCC does support stdint.h, and indeed most of C99
One problem with your suggestion is that the sign of char is implementation defined, so if you do create a type alias. you should at least be explicit about the sign. There is some merit in the idea since in C# for example a char is 16bit. But it has a byte type as well.
Additional note...
There was no problem with your suggestion, you did in fact specify unsigned.
I would also suggest that plain char is used if the data is in fact character data, i.e. is a representation of plain text such as you might display on a console. This will present fewer type agreement problems when using standard and third-party libraries. If on the other hand the data represents a non-character entity such as a bitmap, or if it is numeric 'small integer' data upon which you might perform arithmetic manipulation, or data that you will perform logical operations on, then one of the stdint.h types (or even a type defined from one of them) should be used.
I recently got caught out on a TI C54xx compiler where char is in fact 16bit, so that is why using stdint.h where possible, even if you use it to then define a byte type is preferable to assuming that unsigned char is a suitable alias.
I prefer for types to convey the meaning of the values stored in it. If I need a type describing a byte as it is on my machine, I very much prefer byte_t over unsigned char, which could mean just about anything. (I have been working in a code base that used either signed char or unsigned char to store UTF-8 strings.) The same goes for uint8_t. It could just be used as that: an 8bit unsigned integer.
With byte_t (as with any other aptly named type), there rarely ever is a need to look up what it is defined to (and if so, a good editor will take 3secs to look it up for you; maybe 10secs, if the code base is huge), and just by looking at it it's clear what's stored in objects of that type.
Personally I prefer boost::int8_t and boost::uint8_t.
If you don't want to use boost you could borrow boost\cstdint.hpp.
Another option is to use portable version of stdint.h (link from this answer).
Besides your awkward naming convention, I think that might be okay. Keep in mind boost does this for you, to help with cross-platform-ability:
#include <boost/integer.hpp>
typedef boost::uint8_t byte_t;
Note that usually type's are suffixed with _t, as in byte_t.
I prefer to use standard types, unsigned char, uint8_t, etc., so any programmer looking at the source does not have to refer back to headers to grok the code. The more typedefs you use the more time it takes for others to get to know your typing conventions. For structures, absolutely use typedefs, but for primitives use them sparingly.

Do all C++ compilers allow using a static const int class member variable as an array bound?

In VC++ when I need to specify an array bound for a class member variable I do it this way:
class Class {
private:
static const int numberOfColors = 16;
COLORREF colors[numberOfColors];
};
(please don't tell me about using std::vector here)
This way I have a constant that can be used as an array bound and later in the class code to specify loop-statement constraints and at the same time it is not visible anywhere else.
The question is whether this usage of static const int member variables only allowed by VC++ or is it typically allowed by other widespread compilers?
This is valid C++ and most (all?) reasonably modern compilers support it. If you are using boost, you can get portable support for this feature in the form of BOOST_STATIC_CONSTANT macro:
class Class {
private:
BOOST_STATIC_CONSTANT(int, numberOfColors = 16);
COLORREF colors[numberOfColors];
};
The macro is expanded to static const int numberOfColors = 16 if the compiler supports this, otherwise it resorts to enum { numberOfColors=16 };.
That behavior is valid according to the C++ Standard. Any recent compiler should support it.
I believe that Visual Studio 2005 and beyond supports it. The XCode C++ compiler as well (this is gcc actually).
If you want to be safe you could always use the old enum hack that I learned from Effective C++. It goes like this:
class Class {
private:
enum {
numberOfColors = 16
};
COLORREF colors[numberOfColors];
};
Hope this helps.
This has been standard C++ for more than a decade now. It's even supported by VC -- what more could you want? (#Neil: What about SunCC? :^>)
Yes, it's 100% legal and should be portable. The C++ standard says this in 5.19 - Constant expressions" (emphasis mine):
In several places, C++ requires expressions that evaluate to an integral or enumeration constant: as array bounds (8.3.4, 5.3.4), as case-expressions (6.4.2), as bit-field lengths (9.6), as enumerator initializers (7.2), as static member initializers (9.4.2), and as integral or enumeration non-type template arguments (14.3).
constant-expression:
conditional-expression
An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type template parameters of integral or enumeration types, and sizeof expressions.
That said, it appears that VC6 doesn't support it. See StackedCrooked's answer for a good workaround. In fact, I generally prefer the enum method StackedCrooked mentions for this type of thing.
As an FYI, the "static const" technique works in VC9, GCC 3.4.5 (MinGW), Comeau and Digital Mars.
And don't forget that if you use a "`static const'" member, you'll need a definition for it in addition to the declaration strictly speaking. However, virtually all compilers will let you get away with skipping the definition in this case.
Besides other answers you can use following function do determine number of elements in statically alocated arrays:
template<typename T, size_t length>
size_t arrayLength(T (&a)[length])
{
return length;
}
I'm pretty sure that this will also work with gcc and Solaris, but I can't verify this at the moment.
In the future you could extend the idea like this:
template<int size>
class Class {
private:
COLORREF colors[size];
};
and use it like this:
Class<5> c;
so that you are not limited to exactly one buffer size in your application.
I've stopped bothering about the portability of that years ago. There are perhaps still compilers which don't support it, but I haven't met any of them recently.
It is possible to answer questions like this by referencing the ISO C++ speicifcation but the spec is hard for people to get and harder to read.
I think the simplest answer hinges on two things:
Microsoft Visual Studio 2005 and up is a relatively conformant C++ implementation. If it allows you to do something, chances are its standard.
Download something like Code::Blocks to get a GCC compiler to try stuff out. If it works in MS and GCC, chances really are, its standard.