I'd like gcc to process pack pragmas such as the following:
#define _CTR_PACKING 4
#pragma pack(push, _CRT_PACKING)
MSVC allows this kind of construction by default.
Clang enabled this behavior via -fms-extensions.
Searching for a gcc equivalent, I found references to macros HANDLE_PRAGMA_PACK_PUSH_POP and HANDLE_PRAGMA_PACK_WITH_EXPANSION, but even after adding them via -DHANDLE_PRAGMA_PACK_WITH_EXPANSION=1 or as environment variables, gcc still does nothing.
How can I make gcc behave as MSVC and Clang with -fms-extensions?
The gcc macro HANDLE_PRAGMA_PACK_WITH_EXPANSION is a macro used by gcc target to indicate whether it supports expansion of macros in pragma directive, it's not a switch to enable on the fly.
Instead, you can use standard C's _Pragma operator, it translate into the compiler's pragma directives, and it supports macro expansion since it's part of the language. This is an example:
#define STR(s) #s
#define _CTR_PACKING 1
#define PACKSTR(x) STR(pack(x))
_Pragma(PACKSTR(_CTR_PACKING))
Related
How can I detect if the compiler is truly GCC, and not something pretending to be GCC, using the C preprocessor?
Motivation
Normally, I would test for __GNUC__. However, several compilers that claim to be compatible with GCC will define this, even though they are not fully compatible. Examples are Clang, Intel compiler, PGI.
At this time, I am looking to mark some enum values as deprecated, and I used an approach similar to the following:
#if __GNUC__ >= 6 || defined(__clang__)
#define DEPRECATED_ENUMVAL __attribute__ ((deprecated))
#else
#define DEPRECATED_ENUMVAL
#endif
enum Foo {
A = 0,
B DEPRECATED_ENUMVAL = A
};
This works in GCC version 6 and later, hence the check for __GNUC__ >= 6. However, it does not work with recent Intel and PGI compilers, even though both of those define __GNUC__ to be 7.
It seems that it would be safest to try to detect if I am dealing with specific versions versions of actual GCC or Clang, and restrict the deprecation attribute to them only. How can I detect an actual GCC?
Consider this code:
/* t0.c */
#pragma STDC FENV_ACCESS ON
#include "t0.h"
Then in t0.h how to check the state of STDC FENV_ACCESS?
/* t0.h */
/* how to check the state of STDC FENV_ACCESS? */
/* something like: #if STDC FENV_ACCESS == ON */
If not possible, then:
Why not possible?
Will it be useful to add this feature to the C standard?
(1) Why not possible?
It is possible with a custom cpp as rryker's answer mentioned. Otherwise, I would have said "no" because the compiler uses the pragmas and that comes after the cpp pass/stage.
(2) Will it be useful to add this feature to the C standard?
No, probably not. For the above mentioned reason.
And, because, drawing a leaf from what is already common (e.g. autoconf), we can reverse the problem to get the desired results without changing existing compilers.
Define (e.g.) a features.h:
#ifdef STDC_FENV_ACCESS_ON
#if STDC_FENV_ACCESS_ON
#pragma STDC FENV_ACCESS ON
#else
#pragma STDC FENV_ACCESS OFF
#endif
#endif
UPDATE:
Re: "custom cpp as rryker's answer mentioned": hm, where is the rryker's answer? I don't see it. –
pmor
I wrote that before rryker deleted his answer [partly] because of critique/comments from HolyBlackCat that couldn't be addressed immediately. My inference was rryker would be able to improve his answer and undelete it, so I left up the reference.
The link rryker based his answer on was specific extensions provided by clang: https://clang.llvm.org/docs/LanguageExtensions.html The features that rryker's answer referred to were: the __has_feature and __has_extension macros [since version 10].
That's the reference. However, with a bit of conjecture on my part, I'll try to summarize.
IIRC, clang's cpp is not a separate program that is only loosely connected to the compiler [e.g. like it is with gcc].
With clang, the preprocessor is a [more] tightly integrated stage within the compiler itself. My presumption is that this was [initially] done for speed and code reuse.
But, as a "side effect" of that:
clang's cpp can have much more intimate knowledge of the compiler's inner workings.
And, if it's more efficient/desirable, clang's cpp stage could also do more of the early (e.g.) pragma processing.
And, cpp could have access to (e.g.) all the -f* arguments/options the compiler sees.
So, it has all of the tools that make #if/#ifdef on the above __has_* macros feasible.
In addition to the other answers, and if t0.c is actually under your control, you may define appropriate macros whenever a #pragma is used.
/* t0.c */
#pragma STDC FENV_ACCESS ON
#define PRAG_FENV_ACCESS_ON
#include "t0.h"
This works independently of toolchain vendor. It's a variation of the same theme used to check the presence of typedefs in the preprocessor.
How do I keep __builtin_prefetch() in my code, but make compilers that do not have it compile successfully? (Just doing nothing where it is found).
__builtin_prefetch() is recognised by the compiler (gcc) not the preprocessor, so you won't be able to detect it using the C preprocessor.
Since an identifier with two leading underscores is reserved for use by the implementation (so any code you use which defines such an identifier has undefined behaviour) I'd do it the other way around.
#ifdef __GNUC__
#define do_prefetch(x) __builtin_prefetch(x)
#else
#define do_prefetch(x)
#endif
and then use
do_prefetch(whatever);
where needed.
That way there is no code emitted unless it is actually needed.
Since __builtin_prefetch() accepts a variable number of arguments, you might want to adapt the above to use variadic macros (C99 and later) - if you use it with different numbers of arguments in different places in your code.
It is not exactly the best solution, but it will disable __builtin_prefetch() on all other compilers other than GCC.
#ifndef __GNUC__
# define __builtin_prefetch(x)
#endif
What is the replacement of __attribute__ in ISO C standard?
I want to port my software which is compiler independent.
There isn't one.
One solution is to abstract the attributes behind macros. e.g.:
#ifdef __GNUC__
#define UNUSED __attribute((unused))__
#else
#define UNUSED
#endif
...
void function(void) UNUSED;
There is no general replacement for the wide range of facilities that this gcc extension offers. Most other compilers that are not gcc compatible use #pragma to achieve similar goals. Since C99, C has the _Pragma operator that allows you to spew pragmas in the middle of your code (not only on proper lines) and to compose the contents of a pragma with macros. But then you still have to do specific "translations" of individual features to the corresponding pragma syntax of your target compiler.
Can somebody give me some examples of some pragma in C. Any compiler that he or she is using). If possible gcc,because I am using a gcc compiler.
And how its useful in a C code ??
I can't give you the exact version of my compiler cause I am in office and dont remember it
I believe C99 only recognizes 3 pragmas (6.10.6) (all of them related to floating point)
#pragma STDC CX_LIMITED_RANGE ... /* (7.3.4) */
#pragma STDC FENV_ACCESS ... /* (7.6.1) */
#pragma STDC FP_CONTRACT ... /* (7.12.2) */
Any pragma without STDC has implementation defined behaviour (6.10.6) and, therefore, should best NOT BE USED
An unrecognized STDC pragma invokes Undefined Behaviour.
Why not just check the documentation?
This is the list of GCC's supported pragmas, sorted into various categories.
For example:
#pragma GCC optimize ("string"...)
This pragma allows you to set global optimization options for functions defined later in the source file. One or more strings can be specified. Each function that is defined after this point will be as if attribute((optimize("STRING"))) was specified for that function. The parenthesis around the options is optional. See Function Attributes, for more information about the optimize attribute and the attribute syntax.
The `#pragma GCC optimize' pragma is not implemented in GCC versions earlier than 4.4.