The LLVM libc++ headers have a macro, used in function declarations, named _LIBCPP_INLINE_VISIBILITY.
I don't understand what it means; I looked at its definition, and it says:
// Just so we can migrate to the new macros gradually.
#define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI
... and this second macro has no definition I can find. So, what does _LIBCPP_INLINE_VISIBILITY mean and what is it typically expanded into?
(Thanks, #Ruslan)
The intent is to hide functions marked with it from appearing in dynamic libraries ("hide from the ABI"). This used to be done by making such functions inline only, but now, the clang attribute attribute((internal_linkage)) is used; that's the definition of _LIBCPP_HIDE_FROM_ABI.
As for the inline-for-invisibility macro _LIBCPP_INLINE_VISIBILITY - what you're seeing is it being redefined to what its name should have been to being with.
Related
I was reading the C Preprocessor guide page on gnu.org on computed includes which has the following explanation:
2.6 Computed Includes
Sometimes it is necessary to select one of several different header
files to be included into your program. They might specify
configuration parameters to be used on different sorts of operating
systems, for instance. You could do this with a series of
conditionals,
#if SYSTEM_1
# include "system_1.h"
#elif SYSTEM_2
# include "system_2.h"
#elif SYSTEM_3 …
#endif
That rapidly becomes tedious. Instead, the preprocessor offers the
ability to use a macro for the header name. This is called a computed
include. Instead of writing a header name as the direct argument of
‘#include’, you simply put a macro name there instead:
#define SYSTEM_H "system_1.h"
…
#include SYSTEM_H
This doesn't make sense to me. The first code snippet allows for optionality based on which system type you encounter by using branching if elifs. The second seems to have no optionality as a macro is used to define a particular system type and then the macro is placed into the include statement without any code that would imply its definition can be changed. Yet, the text implies these are equivalent and that the second is a shorthand for the first. Can anyone explain how the optionality of the first code snippet exists in the second? I also don't know what code is implied to be contained in the "..." in the second code snippet.
There's some other places in the code or build system that define or don't define the macros that are being tested in the conditionals. What's suggested is that instead of those places defining lots of different SYSTEM_1, SYSTEM_2, etc. macros, they'll just define SYSTEM_H to the value that's desired.
Most likely this won't actually be in an explicit #define, instead of will be in a compiler option, e.g.
gcc -DSYSTEM_H='"system_1.h"' ...
And this will most likely actually come from a setting in a makefile or other configuration file.
I am looking at this code passed onto me to resolve an issue but I have trouble understanding one of the function's definition.
void DESC_API ApplDesc(DescMsg* pMsg)
I can see that the function isnt returning anything so the void holds good. But what is the DESC_API doing in here? This is how it is defined in the header file
#if defined(DESC_API)
#else
/* No paging used. */
#define DESC_API
#endif
Looks like DESC_API a is visibility macro. It might be defined to __declspec(dllexport) or to __declspec(dllimport) for MSVC or to __attribute__ ((visibility ("default"))) for gcc or clang.
Of course, it might be defined to something else (as said bellow), but the most popular use case is just symbols visibility attributes.
Since gcc and clang export all symbols by default, no attributes is needed and DESC_API is blank. As for MSVC, your build system might set it via /DDESC_API=__declspec(dllimport) externally.
It looks like DESC_API could be used to switch between a function returning nothing and a function returning a void*.
If you define
#define DESC_API *
the function would be returning a void pointer; otherwise, the function would return nothing.
Of course the rest of the function must follow through with a conditional return based on the value of DESC_API.
The macro appears to be a hook by which additional qualifiers can be injected into function signatures. I'm inclined to think that its intended usage is to leverage compiler-specific extensions under certain circumstances, such as to mark functions as using some particular calling convention.
Note that the macro definition you present is conditional. It provides for the macro to be defined (with empty replacement text) in the event that it is not already defined, where a previous definition might come from another header or from a command-line option.
Well, probably does nothing, as you can see by the macro the DESC_API is replaced by blank, hence this is probably a macro used for readability convenience that's it though
Going through the K&R ansi C programming language book (second version), on page 82 an example is given for a programming files/folders layout.
What I don't understand is, while calc.h gets included in main (use of functions), getop.c (definition of getop) and stack.c (definition of push and pop), it does not get included into getch.c, even though getch and ungetch are defined there.
Although it's a good idea to include the header file it's not required as getch.c doesn't actually use the function declared in calc.h, it could even get by if it only used those already defined in getch.c.
The reason it's a good idea to include the header file anyway is because it would provide some safety if you use modern style prototypes and definitions. The compiler should namely complain if for example getop isn't defined in getop.c with the same signature as in calc.h.
calc.h contains the declaration of getch() and ungetch(). It is included by files that want to use these functions (and, therefore, need their signature).
getch.c, instead, contains the definition of getch() and ungetch(). Therefore, there is no need of including their declaration (which is implicitly defined in the definition).
The omission you have so aptly discovered can be a source of a real problem. In order to benefit fully from C's static type checking across a multi-translation-unit program (which is almost anything nontrivial), we must ensure that the site which defines an external name (such as a function) as well as all the sites which refer to the name, have the same declaration in scope, ideally from a single source: one header file where that name is declared.
If the definition doesn't have the declaration in scope, then it is possible to change the definition so that it no longer matches the declaration. The program will still translate and link, resulting in undefined behavior when the function is called or the object is used.
If you use the GNU compiler, you can guard against this problem using -Wmissing-prototypes. Straight from the gcc manual page:
-Wmissing-prototypes (C and Objective-C only)
Warn if a global function is defined without a previous prototype
declaration. This warning is issued even if the definition itself
provides a prototype. The aim is to detect global functions that
fail to be declared in header files.
Without diagnosis, this kind of thing, such as forgetting a header file, can happen to the best of us.
One possible reason why the header was forgotten is that the example project uses the "one big common header" convention. The "one big common header" approach lets the programmer forget all about headers. Everything just sees everything else and the #include "calc.h" which makes it work is just a tiny footnote that can get swallowed up in the amnesia. :)
The other aspect is that the authors had spent a lot of time programming in pre-ANSI "Classic" C without prototype declarations. In Classic C, header files are mainly for common type declarations and macros. The habit is that if a source file doesn't need some type or macros that are defined in some header, then it doesn't need to include that header. A resurgence of that habit could be what is going on here.
For example, in the Zend PHP source:
ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval **argument_array TSRMLS_DC)
Here, ZEND_API is a macro name (previously defined with a #define directive), which is expanded by the preprocessor. It's used to establish a meaningful shorthand for a particular set of directives used in the signature of all Zend API functions; this helps ensure that none of them leave that out, which would cause problems with interop code. It can also be (and, I think, is, although I haven't looked at the Zend source) used to abstract platform differences without changing code in all those locations.
Using a macro in front of a function declaration like that is used to specify calling conventions for certain platforms. In the case of ZEND_API, it expands to
__attribute__ ((visibility("default")))
which tells GCC 4 to make _zend_get_parameters_array visible to other libraries.
Functions are normally visible, so this attribute would usually be a no-op. However, when -fvisibility=hidden is passed to GCC, the default is to hide functions so that they can't be seen from other libraries. "Visible" or "hidden" describe whether the function will get a symbol table entry. This attribute overrides the effect of -fvisibility=hidden by marking a function as visible.*
The ZEND_API macro tells GCC to make _zend_get_parameters_array visible. GCC does that by putting an entry for that function in the symbol table of the compiled library. Without that macro, the function couldn't be called from another library.
See Visibility for more about the visibility attribute of GCC.
*The visibility setting of default means visible.
I have doubts about macros, When we create like the following
#define DATA 40
where DATA can be create? and i need to know size also?and type of DATA?
In java we create macro along with data type,
and what about macro function they are all inline function?
Macros are essentially text substitutions.
DATA does not exist beyond the pre-processing stage. The compiler never sees it. Since no variable is created, we can't talk about its data type, size or address.
Macros are literally pasted into the code. They are not "parsed", but expanded. The compiler does not see DATA, but 40. This is why you must be careful because macros are not like normal functions or variables. See gcc's documentation.
A macro is a fragment of code which has been given a name. Whenever
the name is used, it is replaced by the contents of the macro. There
are two kinds of macros. They differ mostly in what they look like
when they are used. Object-like macros resemble data objects when
used, function-like macros resemble function calls.
You may define any valid identifier as a macro, even if it is a C
keyword. The preprocessor does not know anything about keywords. This
can be useful if you wish to hide a keyword such as const from an
older compiler that does not understand it. However, the preprocessor
operator defined (see Defined) can never be defined as a macro, and
C++'s named operators (see C++ Named Operators) cannot be macros when
you are compiling C++.
macro's are not present in your final executable. They present in your source code only.macro's are processed during pre-processing stage of compilation.You can find more info about macro's here
Preprocessor directives like #define are replaced with the corresponding text during the preprocessing phase of compilation, and are (almost) never represented in the final executable.