C Enum reference undefined, yet sitting in a included header file? - c++

So, I'm playing with GNUTLS, and it has this enum:
typedef enum {
GNUTLS_PK_UNKNOWN = 0,
GNUTLS_PK_RSA = 1,
GNUTLS_PK_DSA = 2,
GNUTLS_PK_DH = 3,
GNUTLS_PK_EC = 4
} gnutls_pk_algorithm_t;
sitting in it's main header file(gnutls.h, version 3.3.17). I reference it here:
unsigned int bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY);
(right out of the example). I do have the #include <gnutls/gnutls.h>, and that all seems to reference fine(other enums are fine, except for GNUTLS_X509_FMT_PEM). I read something about the compiler not seeing gnutls.h, and it is in /usr/local/include and not /usr/include, however I do have that in the Includes side thing in Eclipse. If it is a compiler-not-finding-it, why is it finding some values, and how do I make it find it? If not, what is the issue?

how to find? add -I/usr/local/include to your gcc command line, or CFLAGS in the makefile, or look here for how to add it in eclipse
If the compiler is finding some values while not finding the include, maybe they defined elsewhere. try to redefine them, and look in the error where the other definition is.
to redefine you can declare as different type, (like: typedef int whatever;, to see if and where whatever declared) since if it is the same typedef it may considered as a forward deceleration.

Related

Best code for compiling static const int = X in VS2008 and GCC

I have run into a problem while writing C++ code that needs to compile in Visual Studio 2008 and in GCC 4.6 (and needs to also compile back to GCC 3.4): static const int class members.
Other questions have covered the rules required of static const int class members. In particular, the standard and GCC require that the variable have a definition in one and only one object file.
However, Visual Studio creates a LNK2005 error when compiling code (in Debug mode) that does include a definition in a .cpp file.
Some methods I am trying to decide between are:
Initialize it with a value in the .cpp file, not the header.
Use the preprocessor to remove the definition for MSVC.
Replace it with an enum.
Replace it with a macro.
The last two options are not appealing and I probably won't use either one. The first option is easy -- but I like having the value in the header.
What I am looking for in the answers is a good looking, best practice method to structure the code to make both GCC and MSVC happy at the same time. I am hoping for something wonderfully beautiful that I haven't thought of yet.
I generally prefer the enum way, because that guarantees that it will always be used as immediate value and not get any storage. It is recognized as constant expression by the compiler.
class Whatever {
enum { // ANONYMOUS!!!
value = 42;
};
...
}
If you can't go that way, #ifdef away the definition in the .cpp for MSVC, because if you ifdef away the value in declaration, it will always get storage; the compiler does not know the value, so it can't inline it (well, the "link time code generation" should be able to fix that up if enabled) and can't use it where constant is needed like value template arguments or array sizes.
If you don't dislike the idea of using non-standard hacks, for VC++ there's always __declspec(selectany). My understanding is that it will ensure that at link time, any conflicts are resolved by dropping all but one definition. You can potentially put this in an #ifdef _MSC_VER block.
The Visual C++ 2010 accepts this:
// test.hpp:
struct test {
static const int value;
};
// test.cpp:
#include "test.hpp"
const int test::value = 10;
This is still a problem with VS2013. I've worked around it by putting my standard-compliant definition, in the cpp file, inside a #if preventing VS.
a.h:
class A
{
public:
static unsigned const a = 10;
};
a.cpp:
#ifndef _MSC_VER
unsigned const A::a;
#endif
I also commented it well, so the next guy in the file knows which compiler to blame.

Using C++ with Objective-C, How can I fix "Conflicting declaration 'typedef int BOOL'"?

I have a lot of code in C++, originally built on a PC. I'm trying to make it work with Objective-C on a Mac. To that end, I created an Objective-C framework to house the C++ code and added a thin wrapper. But I'm running into a typedef problem in my C++ code.
When I was working with C++ on a PC I used the BOOL variable defined in WinDef.h. So when I moved everything over the Mac I added in typedef int BOOL; to make sure the BOOL variable would still compile as expected.
But when I try to compile I get an error: "Conflicting declaration 'typedef int BOOL'". I assume this is because BOOL is a keyword in Objective-C, and so is already defined. I also can't just use the Objective-C BOOL since it is an unsigned char and not an int.
While I was looking for possible solutions I found one that mentions undefining BOOL, but I couldn't find how to do that (nor do I know if it actually works). Another suggests renaming BOOL in the C++ files to something that isn't a keyword. This suggestion isn't an option for me because other projects rely on the C++ code. Ideally, any changes I make should stay in one file or at least should not negatively impact the code on a Windows machine.
How can I undefine the Objective-C definition of BOOL for my C++ files and use the C++ definition I added? Is there a better way to deal with this problem?
In case it helps I'm using: Xcode 3.2.5, 64-bit and Mac OS X 10.6.6
Thanks for any guidance!
I'm a little confused by some of the discussion, but instead of typedef int BOOL; how about just:
#ifndef BOOL
#define BOOL int
#endif
If you're using typedef then #undef won't work since they are two different things. #define/#undef operate on preprocessor symbols that perform replacements, whereas a typedef is part of the language that creates an alias of another type.
A preprocessor symbol can be undefined at any point because it is simply an instruction to the preprocessor that tells it to no longer use that definition when performing replacements. However, a typedef can't be undefined, as it is something that gets created within a particular scope, rather than the linear processing that occurs using the preprocessor. (In the same way, you wouldn't expect to be able to declare a global variable int x; and then at some point in your code be able to say 'stop recognizing x as a variable.')
The reason I suggest the #define in my answer is that it's possible that the ObjectiveC #define is being hit only while compiling some of your code. That could be an explanation as to why you may get errors in your C++ when you removed the typedef, but still get a conflict if it is in. But, so, if the assumptions are correct, once you check for the definition prior to trying to define it, you should be able to avoid the conflicting definitions when they occur.
As a final note: in this particular situation, you could also just put your typedef inside the check instead of a #define. However, I gravitated toward doing it the way I did both because it's a very common idiom, and because that block will also prevent you from defining it twice in your C++ code if it ends up included twice. Probably neither very compelling reasons if you very much prefer the typedef and know it's not an issue in the code. :)
AFAIK, BOOL is a #define in Objective-C too. You will have problems with your conflicting BOOL define, even if you manage to
#undef BOOL
because your type and its type do not necessarily match in size and "signedness". Must your BOOL really be an int, instead of whatever it is that Obj-C defines it as? In other words, can't you omit your #define and simply use the Obj-C one?
If you could go back in time, I would say "Don't use typedef int BOOL in your own code".
Now that you've actually done it, though, you are in a bit of a pickle. Generally, you should avoid using external data types for your own code except to interface with external code. Standard types are fine, assuming that you can guarantee compiling with a standard compliant compiler on every platform you target.
The most forward looking solution is to stop using BOOL as a type in your platform agnostic code. In the meantime, you can use all sorts of preprocessor hackery to make your use of BOOL compile, but you might hit some strange link errors if you don't use BOOL in the same way (via #includes) everywhere.
I use cmake to load the freeimage library and i'm using kubuntu 14.x
I had this problem with
"error: conflicting declaration ‘typedef CARD8 BOOL’"
and I thought it would be good to share my solution with people that have this problem!
install FreeImage on Linux:
sudo apt-get install libfreeimage-dev
In my CMakeLists.txt file I have:
set(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY /usr/libs)
find_path(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY, FreeImage.h)
find_library(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY, freeimage)
include_directories(${FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY})
target_link_libraries(freeimage)
And in my main.cpp I have:
#include <FreeImage.h>
#ifndef CARD8
#define BYTE CARD8
#define BOOL CARD8
#endif
And some extra code to capture OpenGl frame on disk:
void generateImage(){
int w, h; // get the width and height of the OpenGL window!
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
GLubyte * pixels = new GLubyte[3*w*h];
glReadPixels(0,0,w,h,GL_RGB,GL_UNSIGNED_BYTE, pixels);
FIBITMAP * image = FreeImage_ConvertFromRawBits(pixels,w,h,3 * w, 24, 0x0000FF, 0xFF0000, 0x00FF00, false);
FreeImage_Save(FIF_BMP,image, "../img/text.bmp",0);
//Free resource
FreeImage_Unload(image);
delete[] pixels;
}
I hope this helps the ones who have problem with this!
Regards
Kahin

Setting a value to an enum in same namespace but different class? C++

EDIT
Thanks to comments under the question, I realized that you have to declare an enum in the header file also. >.< Why does nothing on the internet about enums mention this?
Now the compiler is recognizing Geologist.
My enum is within namespace Star in a class called GameModeState but I need to check the current enum value within a class called ZoneMovementState, which is also using namespace Star. I have GameModeState included at the top of ZoneMovementState.
The enum declaration in GameModeState is this:
enum Job {Landman = 0, Geologist = 1};
I'm trying to use this code in ZoneMovementState:
int placeholderJob = Star::GameModeState::Geologist;
//or I've tried this
int placeholderJob = GameModeState::Geologist;
For some reason my compiler is not recognizing Geologist in either attempt; how do I set placeholderJob to Geologist?
Does it not recognize Geologist in the scope of your program? (When you mouse over does intellisense pop up and show you that Geologist is an enum type equal to 1) or does it have a squigly underneath it (indicating it does not recognize the type?)
This could be a scoping issue (although based on your information it doesn't sound like it), or perhaps the compiler you are using does not allow setting the value of an enumeration to an integer without an explicit cast.
Why does nothing on the internet about enums mention this?
The internet doesn't need to mention this, because it groks compilation units.
Header files are there to tell a compiler (basically) what names (identifiers) exist and what they represent. This is why the compiler tells you when he doesn't know what a Geologist represents.
The same goes for functions, fields, classes, structs, typedefs, namespaces, so really the question would be
Why would a compiler magically know about enums in another compilation unit, when everything else has to be spelled out for him?

g++ C++0x enum class Compiler Warnings

I've been refactoring my horrible mess of C++ type-safe psuedo-enums to the new C++0x type-safe enums because they're way more readable. Anyway, I use them in exported classes, so I explicitly mark them to be exported:
enum class __attribute__((visibility("default"))) MyEnum : unsigned int
{
One = 1,
Two = 2
};
Compiling this with g++ yields the following warning:
type attributes ignored after type is already defined
This seems very strange, since, as far as I know, that warning is meant to prevent actual mistakes like:
class __attribute__((visibility("default"))) MyClass { };
class __attribute__((visibility("hidden"))) MyClass;
Of course, I'm clearly not doing that, since I have only marked the visibility attributes at the definition of the enum class and I'm not re-defining or declaring it anywhere else (I can duplicate this error with a single file).
Ultimately, I can't make this bit of code actually cause a problem, save for the fact that, if I change a value and re-compile the consumer without re-compiling the shared library, the consumer passes the new values and the shared library has no idea what to do with them (although I wouldn't expect that to work in the first place).
Am I being way too pedantic? Can this be safely ignored? I suspect so, but at the same time, having this error prevents me from compiling with Werror, which makes me uncomfortable. I would really like to see this problem go away.
You can pass the -Wno-attributes flag to turn the warning off.
(It's probably a bug in gcc?)
It works for me with g++ 4.8.2 the following way:
enum class MyEnum : unsigned int
__attribute__((visibility("default")))
{
One = 1,
Two = 2
};
(change the position of the attribute declaration)

Remove dependancy constants from enum definition

I am trying to safely remove a dependency from my project by using opaque structures and forward declarations but like most I am still stuck on my enums.
The header file dependency I am trying to remove from my header files has defined constants that I want to set my enumeration's values to. Something like this
// depends header
#define DEP_TYPE_ONE 1
#define DEP_TYPE_TWO 2
#define DEP_TYPE_THREE 3
// My header
enum TYPES
{
T_ONE = DEP_TYPE_ONE,
T_TWO = DEP_TYPE_TWO,
T_THREE = DEP_TYPE_THREE
}
I am trying to figure out a way to not have to include the depends header in my header.
Odds are the answer is probably simply 'you can't do that' but I just want to ask because a solution would make my life infinity easier.
How about removing the include of the depends header, hard code the values, and comment the dependency:
// my_header.h
// NOTE: Enumerands must be in sync with symbols defined in depends.h
enum TYPES
{
T_ONE = 1, // DEP_TYPE_ONE
T_TWO = 2, // DEP_TYPE_TWO
T_THREE = 3 // DEP_TYPE_THREE
};
To allay fears about the values getting out of sync, you can have another header or source file (one that users of your class or API don't get) that contains one or more compile-time asserts:
// Some non-distributed file
#include <depends.h>
#include "my_header.h"
// Compile-time assertion macro
#define compile_time_assert(cond, msg) \
typedef char msg[(cond) ? 1 : -1]
// Check assumptions at compile time...
compile_time_assert(T_ONE==DEP_TYPE_ONE, ValueOutOfSync1);
compile_time_assert(T_TWO==DEP_TYPE_TWO, ValueOutOfSync2);
.
.
.
This would give you a compile time error if the values ever get out of sync.
For more info on the compile_time_assert macro, see: http://www.embedded.com/columns/programmingpointers/164900888?_requestid=379501
It is not what you want, but it is the only way not to include the depends header in your header:
enum TYPES
{
T_ONE = 1,
T_TWO = 2,
T_THREE = 3
}
Not a perfect answer, but have you considered anonymous enums? I had a similar problem once when using a charting library that defined a lot of constants in a header with a lot of internal dependency. This was affecting our compile-time. So, i just MOCked the entire #define's into an anonymous enumeration in an anonymous namespace in a header! Something like :-
namespace {
enum {
DEP_TYPE_ONE = 1,
DEP_TYPE_TWO,
// ....
DEP_TYPE_LAST
};
}
With this approach you will not have to refactor a lot of code that directly uses those named constants. But it is a maintainance nightmare to update the enum as soon as the header defines new constants.
Well worth a try in your case i guess.
HTH,
You are right, you can't. You are dealing with the pre-processor here not the compiler (as with the forward declarations).
It may be possible to 'fake it' if your compiler supports an "forced include" option, but the dependency still remains, and you still need the file to build.