I am writing a program and I would really prefer to write in C++, however, I'm required to include a C header that redefines bool:
# define false 0
# define true 1
typedef int bool;
The obvious solution would be to edit the header to say:
#ifndef __cplusplus
# define false 0
# define true 1
typedef int bool;
#endif
but, alas, since the library is read-only I cannot.
Is there a way I can tell gcc to ignore this typedef? Or, can I write most functions in C++ and then make a C wrapper for the two? Or, should I suck it up and write the thing in C?
You can hack it!
The library, call it fooLib, thinks it's using some type bool which it has the prerogative to define. To the library, bool is just an identifier.
So, you can just force it to use another identifier instead:
#define bool fooLib_bool
#include "fooLib.h"
#undef bool
#undef true
#undef false
Now the compiler sees the offending line transformed to this:
typedef int fooLib_bool;
You're stuck with the interface using type fooLib_bool = int instead of a real bool, but that's impossible to work around, as the code might in fact rely on the properties of int, and library binary would have been compiled with such an assumption baked in.
I suppose you can wrap the offending code into a header and then undef what you don't need
Library_wrapper.h:
#define bool something_else // This will get you past the C++ compilation
#include "library.h"
#undef false
#undef true
#undef bool
main.cpp:
#include "Library_wrapper.h"
#include "boost.h"
Regarding the typedef.. the compiler should complain if you try to redefine a basic type in C++. You can redeclare a type by the way (it is allowed in C++) or define it (simple text replacement).
Unfortunately, no, you cannot use this file in Standard C++:
§7.1.3 [dcl.typedef]
6/ In a given scope, a typedef specifier shall not be used to redefine the name of any type declared in that scope to refer to a different type.
Thus typedef ... bool; is forbidden.
§17.6.4.3.1 [macro.names]
2/ A translation unit shall not #define or #undef names lexically identical to keywords, to the identifiers listed in Table 3, or to the attribute-tokens described in 7.6.
And in §2.12 [lex.key] we find that bool is a keyword.
Thus trying to trick the compiler by using #define bool ... prior to including the offending file is forbidden.
So, what is the alternative ? A shim !
Isolate that offending library behind a C & C++ compatible header of your own; and compile this part as C. Then you can include your own header in the C++ program without issue or tricks.
Note: yes, most compilers will probably accept #define bool ..., but it is still explicitly forbidden by the Standard.
You may copy a bad header and use an edited copy. Tell to compiler the path it should prefer and...
You could compile the code which uses the header as C, then just link it together with your C++ object files. You probably use MSVC or GCC; both can compile code as either C++ or C, and will allow you to create compatible object files.
Whether that's a clean solution or unnecessary overkill really depends on the exact situation.
Related
I've been using C++ and compiling with clang++. I would like to include the <xcb/xkb.h> header for an X11 program I am writing.
Unfortunately this header uses explicit for some field names (such as line 727) and that is a keyword in C++.
Is there anyway to deal with this?
xcb/xkb.h:
// ...
#ifdef __cplusplus
extern "C" {
#endif
// ...
typedef struct xcb_xkb_set_explicit_t {
xcb_keycode_t keycode;
uint8_t explicit;
} xcb_xkb_set_explicit_t;
// ...
#ifdef __cplusplus
}
#endif
// ...
Use a macro to rename the fields:
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wkeyword-macro"
#endif
#define explicit explicit_
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#include <xcb/xkb.h>
#undef explicit
Using a keyword as a macro name is ill-formed in standard C++, but GCC, Clang (with pragma), and MSVC do accept it. (The standard says you "shall not" do it, cppreference clarifies that it means "ill-formed".)
How can I include a C header that uses a C++ keyword as an identifier in C++?
There is no standard-conforming solution to be able to include such header. In order to be able to include a header in C++, it must be written in valid C++. In case of a C header, it would thus have to be written in common subset of C and C++.
The ideal solution is to fix the header to be valid C++. A standard-conforming workaround is to write a C++ conforming wrapper in C.
(Not an answer to the exact question, but possibly useful for the general problem of interfacing C & C++)
How about using an intermediate set of C files (.c & .h) to wrap the incompatible header and provide a C++-compatible interface to the rest of your program? If that interface is high-level enough, then you would only need to include the incompatible header file in the wrapper .c file only, allowing the wrapper .h header file to be included in C++ code normally.
Depending on the details, you might end up doing some trivial copying of data, but the resulting C interface might be much more suited to your specific needs.
One solution is to add a generation step to your makefile that copies the header and renames the field, and include said autogenerated header instead.
(This is between difficult to impossible to do in the general case, but in this case given that the header isn't likely using explicit for anything else even just a simple (gnu) sed (s/\bexplicit\b/explicit_field/g or somesuch) would work. The trickier bit is figuring out the correct file to copy.)
Make sure that the location of the copied header is before the original header in your include path, in case something else in your includes indirectly includes the header.
Just changing a field name shouldn't have any effects on e.g. ABI, at least for a nominally-C-compatible header. (There are cases in C++ where renaming a field does affect things.)
There are lots of tutorials and quesitons addressing this. But I want to confirm my understanding in one specific case. The two below should not make a difference to the compiler i.e either one is correct. Right?
typedef _GridLayoutInputRepeater<_num-1,Figure,_types...> _base;
and
#define _base _GridLayoutInputRepeater<_num-1,Figure,_types...>
Similarly , the below should not make the difference?
#define INT_32 uint32_t
and
typedef uint32_t INT_32;
EDIT : Follow up thread here
Currently without showing use-cases the 2 situations are both "equal" but what you should note is that #define is a whole different beast than typedef.
typedef introduces an alias for another type, this alias will be seen by the compiler and thus will follow compiler rules, scoping etc.
A #define is a preprocessor macro, the preprocessor will run before the actual compiler and will literally do a textual replacement, it does not care about scoping or any syntax rules, it's quite "dumb".
Usually, typedefs are the way to go as they are so much less error-prone. In which case you could use using = as well but that's personal preference since they're both the same:
using _base = _GridLayoutInputRepeater<_num-1,Figure,_types...>;
The problem with using #define rather than typedef or using is that [as has been pointed out] #define is a macro, and macros are evaluated and expanded by the preprocessor, so the compiler knows nothing about the data type you're trying to create because the #define directive is simply substituted with whatever comes after it.
The reason for using macros in languages such as C and C++ is to allow for things that aren't specifically to do with source code logic but are to do with source code structure.
The #include directive, for instance, quite literally includes the entire content of a file in place of the derective.
So, if myfile.h contains:
void func_1(int t);
void func_2(int t);
then
#inlude "myfile.h"
would expand the content of myfile.h, replacing the #include preprocessor directive with
void func_1(int t);
void func_2(int t);
The compiler then comes along and compiles the expanded file with class definitions, and other expanded macros!
It's why the macro
#pragma once
or
#ifndef __MYFILE_INCLUDE__
#define __MYFILE_INCLUDE__
is used at the start of header files to prevent multiple definitions occurring.
When you use an expression like #define INT64 unsigned int the preprocessor does exactly the same thing. It evaluates the expression, then replaces all occurrences of INT64 with unsigned int.
When you use a typedef, on the other hand, the compiler makes the type substitution, which means the compiler can warn about incorrect use of your newly created type.
#define would simply warn you of an incorrect use of unsigned int which if you have a lot of type substitution can become confusing!
My data type called "Bool" which is inside a namespace conflicts with #define Bool int which is defined in some Xlib header file. Also, the same thing happens when I put an element called "None" inside any enumerator, because of the definition #define None 0L.
I've tried to use #undef Bool in multiple files, but it just turned into a mess.
Should I rename the data type to something like "Boolean" and stop using "None" for good?
If you're doing Xlib programming, you will want to avoid redefining Bool, True, False and None (as well as XID and XPointer and Status) to avoid conflicts with the #define and typedef values in the Xlib headers.
Since you're using C++11, you should either use the Xlib Bool or use the standard C++ bool in your code. Your life will be easier if you can isolate the Xlib #include files to as few compilation units (source files) as possible and use the standard C++ bool everywhere else.
If I want to define a value only if it is not defined, I do something like this :
#ifndef THING
#define THING OTHER_THING
#endif
What if THING is a typedef'd identifier, and not defined? I would like to do something like this:
#ifntypedef thing_type
typedef uint32_t thing_type
#endif
The issue arose because I wanted to check to see if an external library has already defined the boolean type, but I'd be open to hearing a more general solution.
There is no such thing in the language, nor is it needed. Within a single project you should not have the same typedef alias referring to different types ever, as that is a violation of the ODR, and if you are going to create the same alias for the same type then just do it. The language allows you to perform the same typedef as many times as you wish and will usually catch that particular ODR (within the same translation unit):
typedef int myint;
typedef int myint; // OK: myint is still an alias to int
//typedef double myint; // Error: myint already defined as alias to int
If what you are intending to do is implementing a piece of functionality for different types by using a typedef to determine which to use, then you should be looking at templates rather than typedefs.
C++ does not provide any mechanism for code to test presence of typedef, the best you can have is something like this:
#ifndef THING_TYPE_DEFINED
#define THING_TYPE_DEFINED
typedef uint32_t thing_type
#endif
EDIT:
As #David, is correct in his comment, this answers the how? part but importantly misses the why? It can be done in the way above, If you want to do it et all, but important it you probably don't need to do it anyways, #David's answer & comment explains the details, and I think that answers the question correctly.
No there is no such facility in C++ at preprocessing stage. At the max can do is
#ifndef thing_type
#define thing_type uint32_t
#endif
Though this is not a good coding practice and I don't suggest it.
Preprocessor directives (like #define) are crude text replacement tools, which know nothing about the programming language, so they can't act on any language-level definitions.
There are two approaches to making sure a type is only defined once:
Structure the code so that each definition has its place, and there's no need for multiple definitions
#define a preprocessor macro alongside the type, and use #ifndef to check for the macro definition before defining the type.
The first option will generally lead to more maintainable code. The second could cause subtle bugs, if you accidentally end up with different definitions of the type within one program.
As other have already said, there are no such thing, but if you try to create an alias to different type, you'll get a compilation error :
typedef int myInt;
typedef int myInt; // ok, same alias
typedef float myInt; // error
However, there is a thing called ctag for finding where a typedef is defined.
The problem is actually real PITA, because some APIs or SDKs redefine commonly used things. I had issue that header files for a map processing software (GIS) were redefining TRUE and FALSE (generally used by windows SDK)keywords to integer literals instead of true and false keywords ( obviously, that can break SOMETHING). And yes, famous joke "#define true false" is relevant.
define would never feel a typedef or constant declared in C\C++ code because preprocessor doesn't analyze code, it only scans for # statements. And it modifies code prior to giving it to syntax analyzer. SO, in general, it's not possible.
https://msdn.microsoft.com/en-us/library/5xkf423c.aspx?f=255&MSPPError=-2147217396
That one isn't portable so far, though there were known request to implement it in GCC. I think, it also counts as "extension" in MSVC. It's a compiler statement, not a preprocessor statement, so it will not "feel" defined macros, it would detect only typedefs outside of function body. "full type" there means that it will react on full definition, ignoring statements like "class SomeClass;". Use it at own risk.
Edit: apparently it also supported on MacOS now and by Intel comiler with -fms-dialect flag (AIX\Linux?)
This might not directly answer the question, but serve as a possible solution to your problem.
Why not try something like this?
#define DEFAULT_TYPE int // just for argument's sake
#ifndef MY_COOL_TYPE
#define MY_COOL_TYPE DEFAULT_TYPE
#endif
typedef MY_COOL_TYPE My_Cool_Datatype_t;
Then if you want to customize the type, you can either define MY_COOL_TYPE somewhere above this (like in a "configure" header that is included at the top of this header) or pass it as a command line argument when compiling (as far as I know you can do this with GCC and LLVM, maybe others, too).
No there is nothing like what you wanted. I have had your same problem with libraries that include their owntypedefs for things like bool. It gets to be a problem when they just don't care about what you use for bool or if any other libs might be doing the same thing!!
So here's what I do. I edit the header file for the libs that do such things and find the typedef bool and add some code like this:
#ifdef USE_LIBNAME_BOOL
typedef unsigned char bool; // This is the lib's bool implementation
#else
#include <stdbool.h>
#endif
Notice that I included if I didn't want to use the libs' own bool typdef. This means that you need C99 support or later.
As mentioned before this is not included in the C++ standard, but you might be able to use autotools to get the same functionality.
You could use the ac_cxx_bool macro to make sure bool is defined (or different routines for different datatypes).
The solution I ended up using was including stdbool.h. I know this doesn't solve the question of how to check if a typedef is already defined, but it does let me ensure that the boolean type is defined.
This is a good question. C and Unix have a history together, and there are a lot of Unix C typedefs not available on a non-POSIX platform such as Windows (shhh Cygwin people). You'll need to decide how to answer this question whenever you're trying to write C that's portable between these systems (shhhhh Cygwin people).
If cross-platform portability is what you need this for, then knowing the platform-specific preprocessor macro for the compilation target is sometimes helpful. E.g. windows has the _WIN32 preprocessor macro defined - it's 1 whenever the compilation target is 32-bit ARM, 64-bit ARM, x86, or x64. But it's presence also informs us that we're on a Windows machine. This means that e.g. ssize_t won't be available (ssize_t, not size_t). So you might want to do something like:
#ifdef _WIN32
typedef long ssize_t;
#endif
By the way, people in this thread have commented about a similar pattern that is formally called a guard. You see it in header files (i.e. interfaces or ".h" files) a lot to prevent multiple inclusion. You'll hear about header guards.
/// #file poop.h
#ifndef POOP_H
#define POOP_H
void* poop(Poop* arg);
#endif
Now I can include the header file in the implementation file poop.c and some other file like main.c, and I know they will always compile successfully and without multiple inclusion, whether they are compiled together or individually, thanks to the header guards.
Salty seadogs write their header guards programmatically or with C++11 function-like macros. If you like books I recommend Jens Gustedt's "Modern C".
It is not transparent but you can try to compile it one time without typedef (just using the alias), and see if it compiles or not.
There is not such things.
It is possible to desactivate this duplicate_typedef compilator error.
"typedef name has already been declared (with same type)"
On a another hand, for some standardized typedef definition there is often a preprocessor macro defined like __bool_true_false_are_defined for bool that can be used.
I've written a collection of data structures and functions in C, some of which use the _Bool data type. When I began, the project was going to be pure C. Now I am investigating using a C++ based GUI tool kit and have made the backend code into a library.
However, when compiling the C++ GUI the following error is emitted by the compiler:
ISO C++ forbids declaration of '_Bool' with no type
I initially thought I could search & replace _Bool to bool and create:
/* mybool.h */
#ifndef MYBOOL_H
#define MYBOOL_H
typedef _Bool bool;
#endif /* MYBOOL_H */
and then in any headers that use _Bool
#ifdef __cplusplus
extern "C" {
#else
#include "mybool.h"
#endif
/* rest of header... */
Until I realized this would be compiling the library with one boolean (C _Bool) data type, and linking against the library using another (C++ bool). Practically, this might not matter, but theoretically, it probably does (there might be some obscure system somewhere which doing so like this causes the universe to turn inside out).
I suppose I could just use an int and use 0 for false and 1 for true, and typedef it with something like typedef int mybool, but it seems unattractive.
Is there a better/idiomatic/standard way to do this?
If the C and C++ compilers you are using are from the same vendor then I would expect the C _Bool to be the same type as C++ bool, and that including <stdbool.h> would make everything nicely interoperable. If they are from different vendors then you'll need to check for compatibility.
Note, you can always test the __cplusplus macro in your header to determine whether or not the code is being compiled as C++, and set the types appropriately.
Formally, there's no solution for this problem. Type _Bool exists only in C. C++ language does not provide any type that would guarantee binary compatibility with _Bool. C++ bool is not guaranteed to be compatible.
The proper solution is not to use bool or _Bool in parameter declarations of C functions that are intended to be directly accessible (i.e. linkable) from C++ code. Use int, char or any other type that is guaranteed to be compatible.
Just #include <stdbool.h> and use bool.
I think that one must use bool in any project, in order to have compatibility with C++, if neccessary.
The data type _Bool in C99 exists to avoid conflicts with possible existent versions of bool that programmers could have been defined before the standard C99.
Thus, the programmer can choose the better way to adapt their old C programs to migrate toward the new standard.
Thus, I think that to use the word bool is the truly desire of C99 standarization commitee, but it have been forced to surround incompatibility issues by defining the ugly word _Bool.
This shows that the programmer probably have to use the "intended" word bool in his/her projects. It is the most logical word to declare a boolean type in a program.
In some cases, it could be good idea to keep a programmer preexistent definition of bool and, in other cases, it would be better to use the bool version defined in <stdbool.h>.
The programmer have to decide what is better in each case and besides, maybe, to consider if a gradual migration to <stdbool.h> is a good action to take.
If you are starting a project from zero, then probably the best approach is ever to use bool defined in <stdbool.h>.
use typedef int _Bool for both your C and C++ code. I will be surprised if _Bool is defined as anything else.