These are defined in minwindef.h (which is often located at Program Files (x86)\Windows Kits\8.1\Include\shared\minwindef.h)
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
And I often see parameters decorated with these macros like this:
void SomeFunction(IN const MyClass& obj)
What is the significance of these macros and why one should decorate parameters with it?
These macros may be defined as nothing for compatibility with Standard C and Standard
C++ or they can be defined as MS-specific SAL (Microsoft source code annotation language) annotations
for Annotating Function Parameters and Return Values, e.g.
#define IN _In_
#define OUT _Out_
with the documented meanings:
_In_
Annotates input parameters that are scalars, structures, pointers to structures and the like. Explicitly may be used on simple scalars. The parameter must be valid in pre-state and will not be modified.
_Out_
Annotates output parameters that are scalars, structures, pointers to structures and the like. Do not apply this to an object that cannot return a value—for example, a scalar that's passed by value. The parameter does not have to be valid in pre-state but must be valid in post-state.
SAL annotations are parsed by MS compilers, of course. MSDN Windows API documentation
employs the SAL annotations, for example
As you can see from their definitions, these macros have no functional use whatsoever.
They are used there only for documentation purposes, to indicate that the function's logical semantics expect, for example, obj to be an "in" parameter, as opposed to an "out" parameter.
C# has actual keywords in and out, so it's possible that the Windows code includes these equivalents for "consistency" … though, personally, I think having "equivalents" that actually don't do anything, likely does more harm than good.
But, hey, you're the one who works for Microsoft, so perhaps you can tell us. :)
Related
There's a macro defined as:
#define SET_ARRAY(field, type) \
foo.field = bar[#field].data<type>();
foo is a structure with members that are of type int or float *. bar is of type cnpy::npz_t (data loaded from .npz file). I understand that the macro is setting the structure member pointer so that it is pointing to the corresponding data in bar from the .npy file contained in the .npz file, but I'm wondering about the usage bar[#field].
When I ran the code through the preprocessor, I get:
foo.struct_member_name = bar["struct_member_name"].data<float>();
but I've never seen that type of usage either. It looks like the struct member variable name is somehow getting converted to an array index or memory offset that resolves to the data within the cnpy::npz_t structure. Can anyone explain how that is happening?
# is actually a preprocessor marker. That means preprocessor commands (not functions), formally called "preprocessor directives", are being executed at compile time. Apart from commands, you'll also find something akin to constants (meaning they have predefined values, either static or dynamic - yes I used the term constants loosely, but I am oversimplifying this right now), but they aren't constants "in that way", they just seem like that to us.
A number of preprocessor commands that you will find are:
#define, #include, #undef, #if (yes, different from the normal "if" in code), #elif, #endif, #error - all those must be prefixed by a "#".
Some values might be the __FILE__, __LINE__, __cplusplus and more. These are not prefixed by #, but can be used in preprocessor macros. The values are dynamically set by the compiler, depending on context.
For more information on macros, you can check the MS Learn page for MSVS or the GNU page for GCC. For other preprocessor values, you can also see this SourceForge page.
And of course, you can define your own macro or pseudo-constants using the #define directive.
#define test_integer 7
Using test_integer anywhere in your code (or macros) will be replaced by 7 after compilation. Note that macros are case-sensitive, just like everything else in C and C++.
Now, let's talk about special cases of "#":
string-izing a parameter (also called "to stringify")
What that means is you can pass a parameters and it is turned into a string, which is what happened in your case. An example:
#define NAME_TO_STRING(x) #x
std::cout << NAME_TO_STRING(Hello) << std::endl;
This will turn Hello which is NOT a string, but an identifier, to a string.
concatenating two parameters
#define CONCAT(x1, x2) x1##x2
#define CONCAT_STRING(x1, x2) CONCAT(#x1,#x2)
#define CONCATENATE(x1, x2) CONCAT_STRING(x1, x2)
(yes, it doesn't work directly, you need a level of indirection for preprocessor concatenation to work; indirection means passing it again to a different macro).
std::cout << CONCATENATE(Hello,World) << std::endl;
This will turn Hello and World which are identifiers, to a concatenated string: HelloWorld.
Now, regarding usage of # and ##, that's a more advanced topic. There are many use cases from macro-magic (which might seem cool when you see it implemented - for examples, check the Unreal Engine as it's extensively used there, but be warned, such programming methods are not encouraged), helpers, some constant definitions (think #define TERRA_GRAV 9.807) and even help in some compile-time checks, for example using constexpr from the newest standards.
If you're curious what is the advantage of using #define versus a const float or const double, it might also be to not be part of the code (there is no actual syntax check on macros if they are not used).
In regards to helper macros, the most common are defining exports when building a library (search __declspec for MSVS and __attribute__ for GCC), the old style inclusion limitators (now replaced by #pragma once) to stop a *.h, *.hxx or *.hpp from being included multiple times in projects and debug handling (search for _DEBUG and assertions on Google). This paragraph handles slightly more advanced topics so I won't cover them here.
I tried to keep the explanation as simple as possible, so the terminology is not that formal. But if you really are curious, I am sure you can find more details online or you can post a comment on this answer :)
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'm new to, and learning C++ (know a lot of Java) and the following code confuses me...
I know this code fragment is dealing with a pointer-to-function (it's a callback, that makes sense) but what is throwing me off is the argument between the return type and the function name. What the bloody hell is that?
It looks like a type of function, but I have never heard of that and even after searching and reading about pointer-to-functions I was not able to find anything mentioning that functions could have a type.
If this is true, how does one define a function type?
Thanks, -Cody
GLFWCALL is not a type, it's a macro which is expanded to a calling convention specific to the platform, or an empty string. Here's a trimmed fragment of glfw.h:
#if defined(_WIN32) && defined(GLFW_BUILD_DLL)
#define GLFWCALL __stdcall
#elif defined(_WIN32) && defined(GLFW_DLL)
#define GLFWCALL __stdcall
#else
/* We are either building/calling a static lib or we are non-win32 */
#define GLFWCALL
#endif
Using a correct calling convention is important on x86/win32, since some of them expect the stack to be cleaned by callee and others by the caller. There can also be differences in the order of passing the arguments.
On Windows, GLFWCALL is a macro for __stdcall, and on other platforms, it's a macro for nothing.
__stdcall implements a particular calling convention, and is a compiler extension on top of normal C or C++.
Macros are pieces of code that do replacements on your code before the lexer and parser of your compiler interact with them.
The GLFWCALL is a macro that can expand to a calling convention if one is needed. Because this function will be called by external code, it has to use the calling convention that external code expects. For example, if the function puts its return value on the stack and the external code expects it in a register, boom.
The question marked part of the function signature is a preprocessor macro that is defined somewhere else in the header. Certain features on certain platforms have extra requirements.
For example functions in DLL files on the Windows platform often make use of the __declspec(dllexport) modifier but when the same header is included in a user's project they need to use __declspec(dllimport). Using a preprocessor macro for that purpose means they can just use that macro on all relevant functions and simply define the macro differently when compiling their own DLL or a user's DLL and on platforms where __declspec is irrelevant it can be defined to nothing. There are many other reasons for macros like that one.
In this particular case you can effectively pretend that macro is blank and ignore it entirely.
I am trying to build a program that parses and lists the content of header files. So far, so good, I found it easy parsing and listing headers I wrote, but when I started parsing cross platform API headers things got messy.
My current approach is rather simplistic, here is a pseudocode example of parsing the following function:
void foo(int a);
void is a type, so we are dealing with instancing a type
foo is the name of that type
foo is followed by brackets, meaning it is a function of type void named foo
int is a type...
a is the name of that type instance
foo is a function of type void that takes one parameter of type int named a
However, when I got into bigger and more complex headers I stumbled upon somewhat irregular prototypes, involving macros and god knows what. An example:
GLAPI void APIENTRY glEvalCoord1d( GLdouble u );
GLAPI and APIENTRY are platform dependent macros. Which kind of spoils my simple parsing scheme, since it expects the name of an object to follow its type. Those two macros happen to translate to either __stdcall, __declspec(dllimport) or extern but in theory they could mean anything, with their meaning being unclear until compile time.
How to write my parser so it can deal with such scenarios and not get confused? The macros themselves are defined at an earlier stage, so the parser can be aware GLAPI and APIENTRY are macros so they can simply be ignored, is this the way to go? Naturally this is just one of the many variations of irregularities the parser may stumble upon parsing through different headers, so any general techniques of how to deal with the parsing of any "legal" header content are welcome.
There isn't any real alternative to expanding the macros before you parse, at least if you want process header files with the same complexity as Microsoft's, or any other header files associated with a compiler system that has been around for 10 years or more.
The unpreprocessed source code is NOT C; it is simply unpreprocessed source code. The macros (and prepreprocessor conditionals which you surprising didn't mention) can edit the apparant source in not arbitrary but spectacularly complex fashion. And you can't often know what the macros used, or conditionals expanded, unless you process the #includes as well.
You can get GCC to do preprocessor expansion for you, and then parse it. That would be far
the easiest way to approach this.
That still leaves the problem of parsing real C code, with all the complexities of declarators, and ambiguities in fragments suchas T X; where the meaning of the statement depends on the declaration of T. To parse the headers accurately, you need a full C parser.
Our C Front End can do full preprocessing, or you can invoke it a mode in which some macros are expanded, and some are not. By tuning this set, you often parse such headers without exapanding every macro. Preprocessor conditionals are much more difficult, because they can occur at inconvenient (unstructured) places.
If all you want is the name and signature of functions, then a simple search and replace for macros should be sufficient.
However, you need to check if a macro contains keywords (like the return value). This may be possible by stripping macro definitions of every but keywords as they are defined, but tracking them and using a simple preprocessor will be necessary.
The platform dependent keywords, such as __declspec and __attribute__ have very limited syntax and there are only a few of them, so specifically removing those is possible.
You may want to take a look at how doxygen handles this, because it does almost exactly what you want and does handle macros. It allows a list of macros to be expanded as defined, and ones that should be expanded to a custom value. You could adapt that to expand __declspec(x) to nothing, and expand all others to their defined value by default.
This certainly isn't foolproof, but a search and replace is about the simplest functional solution you'll get. You need to follow the standard C++ preprocessor rules, which aren't terribly complex, with additional macros (const, declspec, etc) to strip extra attributes, and parse the final results.
After browsing some old code, I noticed that some classes are defined in this manner:
MIDL_INTERFACE("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
Classname: public IUnknown {
/* classmembers ... */
};
However, the macro MIDL_INTERFACE is defined as:
#define MIDL_INTERFACE(x) struct
in C:/MinGW/include/rpcndr.h (somewhere around line 17). The macro itself is rather obviously entirely pointless, so what's the true purpose of this macro?
In the Windows SDK version that macro expands to
struct __declspec(uuid(x)) __declspec(novtable)
The first one allows use of the __uuidof keyword which is a nice way to get the guid of an interface from the typename. The second one suppresses the generation of the v-table, one that is never used for an interface. A space optimization.
This is because MinGW does not support COM (or rather, supports it extremely poorly). MIDL_INTERFACE is used when defining a COM component, and it is generated by the IDL compiler, which generates COM type libraries and class definitions for you.
On MSVC, this macro typically expands to more complicated initialization and annotations to expose the given C++ class to COM.
If I had to guess, it's for one of two use cases:
It's possible that there's an external tool that parses the files looking for declarations like these. The idea is that by having the macro evaluate to something harmless, the code itself compiles just fine, but the external tool can still look at the source code and extract information out of it.
Another option might be that the code uses something like the X Macro Trick to selectively redefine what this preprocessor directive means so that some other piece of the code can interpret the data in some other way. Depending on where the #define is this may or may not be possible, but it seems reasonable that this might be the use case. This is essentially a special-case of the first option.