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!
Related
I am trying to making a board-specific API (C++) more generic. I have access to their .h file. At the top of the header file, they "redfine" boolean and ulong types as such ('unique' replacing their proprietary name):
#ifndef UNIQUEDLLAPI
#define UNIQUEDLLAPI
#endif
#ifndef UNIQUEAPI
#define UNIQUEAPI
#endif
#define uniqueret_bool UNIQUEDLLAPI unsigned int UNIQUEAPI
#define uniqueret_ulong UNIQUEDLLAPI unsigned long UNIQUEAPI
Could someone explain the syntax to me?
I know that the "definition" of this directive is: #define identifier token-string-opt, and it seems to do something similar to:
#define unsigned long ulong
so that it's easier typing. But I just don't understand the syntax that they wrote, as whoen above. How do the previous definitions (i.e. UNIQUEDLLAPI and UNIQUEAPI) come into play?
Are there any issues with typecasting these types back to bool and ulong? Can I just cast, for example:
uniqueret_bool a;
if ((bool) a) {...}
or would I have to do something else to make this work?
Also, any suggestions to a better/more accurate title for question would be appreciated -- I don't really even know how to phrase it.
These are not types, they are function declaration helpers, that annotate the function types with platform-specific goodies such as __stdcall and __declspec(dllimport) (with Microsoft compilers. GCC has __attribute__). There's no particular rhyme or reason controlling which of these go before the return type and which come after, the developer apparently chose to use a macro to encode that rather than memorizing the correct order.
Compare to Microsoft's similar macro, STDMETHOD:
#define STDMETHODCALLTYPE __stdcall
#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method
Remember that macros are simple (but powerful) text-substitution, they are not just an archaic form of typedef.
To address your proposed usage, the answer is that you should not use these macros with variable declarations, only functions (maybe for function pointers). To capture the return value from a call to such a function, use unsigned int or unsigned long as the type, not these macros.
The conditional definition are there to prevent compilation errors if the names are not previously defined. Potentially, this kind of structure can be used to have some modifiers on the variable types.
Consider what happens if UNIQUEDLLAPI is predefined (either from an earlier header, or using a command line option) to be equal to 'const'.
The flow would would SKIP the first #ifndef and leave UNIQUEDLLAPI as it is, and later the type definitions will be of const types.
Regarding the validity of casting, that depends on the actual usage of the 2 "decorating" defines.
They probably want another datatype if UNIQUEAPI is defined mabe a unsigned long long instead of a unsigned long.
Bool is not available in ANSI C so a simple cast would not be possible here.
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.
Working with a unit test framework, I came across a situation in which I'd like to test macro arguments. Simply said, I'd like to expand the macro FOO(x) such that FOO(int) would be short and FOO(anything_else) would be long.
With C++ templates, of course this isn't a problem. But here I need a real token replacement, not just a typedef. I.e. FOO(char) FOO(char) i; should be a valid definition equal to long long i;.
As far as I know, the only string-like operations available in C macros are pasting/concatenating tokens (using ##), and string-izing them (using #).
I'm pretty sure the closest you're going to get involves enumerating the possibilities like so:
#define FOO(x) FOO__##x
#define FOO__int short
#define FOO__short long
#define FOO__long long
#define FOO__char long
// ... for each type you want to replace
Inspiration from this question.
what you are trying to do is impossible.
Macros are evaluated by the c preprocessor, which as the name implies runs before the compiler runs. It doesn't know what the types of your symbols are yet.
Why don't you create a class for the type that casts itself to the right thing at the time it is evaluated by the compiler.
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.
What is the role of the #define directive?
#define is used to create macros in C and in C++. You can read more about it in the C preprocessor documentation. The quick answer is that it does a few things:
Simple Macros - basically just text replacement. Compile time constants are a good example:
#define SOME_CONSTANT 12
simply replaces the text SOME_CONSTANT with 12 wherever it appears in your code. This sort of macro is often used to provide conditional compilation of code blocks. For example, there might be a header included by each source file in a project with a list of options for the project:
#define OPTION_1
#define OPTION_2
#undef OPTION_3
And then code blocks in the project would be wrapped with matching #ifdef/#endif# blocks to enable and disable those options in the finished project. Using the -D gcc flag would provide similar behaviour. There are strong opinions as to whether or not this method is really a good way to provide configuration for an application, however.
Macros with arguments - allows you to make 'function-like' macros that can take arguments and manipulate them. For example:
#define SQUARE(x) ((x) * (x))
would return the square of the argument as its result; be careful about potential order-of-operations or side-effect problems! The following example:
int x = SQUARE(3); // becomes int x = ((3) * (3));
will works fine, but something like:
int y = SQUARE(f()); // becomes int y = ((f()) * (f()));
will call f() twice, or even worse:
int z = SQUARE(x++); // becomes int z = ((x++) * (x++));
results in undefined behaviour!
With some tools, macros with arguments can also be variadic, which can come in handy.
As mentioned below in the comments, overuse of macros, or the development of overly complicated or confusing macros is considered bad style by many - as always, put the readability, maintainability, and debuggability of your code above 'clever' technical tricks.
#define (and it's opposite, #undef) can be used to set compiler directives which can then be tested against using #ifndef or #ifdef. This allows for custom behaviors to be defined within the source file. It's used commonly to compile for different environments or debug code.
An example:
#define DEBUG
#ifdef DEBUG
//perform debug code
#endif
The most common use (by far) of #define is for include guards:
// header.hh
#ifndef HEADER_HH_
#define HEADER_HH_
namespace pony {
// ...
}
#endif
Another common use of #define is in creating a configuration file, commonly a config.h file, where we #define macros based on various states and conditions. Then, in our code we test these macros with #ifdef, #elif defined() etc. to support different compiles for different situations. This is not as solid as the include-guard idiom and you need to be careful here because if the branching is wrong then you can get very obscure compiler errors, or worse, runtime behavior.
In general, other than for include guards you need to think through (twice, preferably) about the problem, and see if you can use the compiler rather than the preprocessor to solve it. The compiler is just smarter than the preprocessor. Not only that, but the compiler can't possibly confuse the preprocessor, whereas the preprocessor most definitely can confuse and mislead the compiler.
The #define directive has two common uses.
The first one, is control how the compiler will act. To do this, we also need #undef, #ifdef and #ifndef. (and #endif too...)
You can make "compiler logic" this way. A common use is to activate or not a debug portion of the code, like that:
#ifdef DEBUG
//debug code here
#endif
And you would be able to for example compile the debug code, by writing a #define DEBUG
Another use of this logic stuff, is to avoid double includes...
Example, file A, #includes file B and C. But file B also includes C. This likely will result in a compilation error, because "C" exists twice.
The solution is write:
#ifndef C_FILE_INCLUDED
#define C_FILE_INCLUDED
//the contents of header "c" go here.
#endif
The other use of #define, is make macros.
The most simple ones, consist of simple substitutions, like:
#define PI 3.14159265
float perimeter(float radius) {
return radius*2*PI;
}
or
#define SHOW_ERROR_MESSAGE printf("An serious error happened");
if ( 1 != 1 ) { SHOW_ERROR_MESSAGE }
Then you can also make macros that accept arguments, printf itself usually is a macro, created with a #define in a header file.
But this should not be done, for two reaons:
first, the speed os macros, is the same of using inline, and second, we have c++ templates, that allow more control over functions with variable type. So, the only reason to use macros with arguments, is make strange constructs, that will be hard to understand later, like metaprogrammed stuff...
In C++, #define has very narrow, specialized roles:
Header guards, described in other answers
Interacting with the standard libraries. For instance, #defining WINDOWS_LEAN_AND_MEAN before including windows.h turns off certain often-problematic macros like MAX.
Advanced macros involving stringization (ie, macros that print debugging messages) or token-pasting.
You should avoid using #define for the following purposes. The reasons are many; see for instace this FAQ entry.
Compile-time constants. Use const instead.
Simple macro functions. Use inline functions and templates instead.
in C or C++ #define allows you to create preprocessor Macros.
In the normal C or C++ build process the first thing that happens is that the PreProcessor runs, the preprocessor looks though the source files for preprocessor directives like #define or #include and then performs simple operations with them.
in the case of a #define directive the preprocessor does simple text based substitution.
For example if you had the code
#define PI 3.14159f
float circum = diameter*PI;
the preprocessor would turn it into:
float circum = diameter* 3.14159;
by simply replacing the instances of PI with the corresponding text. This is only the simplest form of a #define statement for more advanced uses check out this article from MSDN
inCorrectUseOfHashDefine()
{
The role of #define is to baffle people who inherit your code with out of the blue statements like:
foreverandever
because of:
#define foreverandever for(;;)
}
Please favour constants over #define.
It also for setting compiler directives...
Most things about #defines have been already told, but it's not clear that C++ has better replacements for most of their uses:
#define to define numerical constants can be easily replaced by a const "variable", that, as a #define, doesn't really exist in the compiled executable. AFAIK it can be used in almost all the situations where you could use a #defined numerical constant, including array bounds. The main advantage for me is that such constants are clearly typed, so there's no need to add casts in the macros "just to be sure", and are scoped, so they can be kept in namespaces/classes/functions, without polluting all the application.
const int max_array_size=50;
int an_array[max_array_size];
#define to create macros: macros can often be replaced by templates; for example, the dreaded MAX macro
#define MAX(a,b) ((a)<(b)?(b):(a))
, which has several downsides (e.g. repeated arguments evaluation, inevitable inline expansion), can be replaced by the max function
template<typename T> T & max(T & a, T & b)
{
return a<b?b:a;
}
which can be type-safe (in this version the two arguments are forced to be of the same type), can be expanded inline as well as not (it's compiler decision), evaluates the arguments just once (when it's called), and is scoped. A more detailed explanation can be found here.
Still, macros must still be used for include guards, to create some kind of strange language extensions that expand to more line of code, that have unbalanced parenthesis, etc.