What is gcc option to ignore unused condition - gcc

#if !__STDC__ && (_MSC_VER <= 1000) && !defined(__BORLANDC__)
/* For backward compatibility */
typedef VARIANT_BOOL _VARIANT_BOOL;
#else
/* ANSI C/C++ reserve bool as keyword */
#define _VARIANT_BOOL /##/
#endif
This code is copied from a header file and #if block is active and #else block is disabled but gcc doesn't ignore inactive block.
....\wtypes.h|1071|error: pasting "/" and "/" does not give a valid preprocessing token
I know what gcc is saying but I don't want to modify the code for different compilers. The code MUST REMAIN UNTOUCHED.
How can I tell gcc to ignore unused code?

Related

Error installing perl on Win10 using MinGW

If this is the wrong place for this question I apologise and please redirect me to the suitable section.
I'm somewhat rusty on installing from command line, especially on Windows. I decided to install the latest Perl version on my PC, running under Windows 10. I had previously installed it using Strawberry Perl download, but as it was a few versions out of date I decided to remove it and refresh my skills (ha) by installing it manually. I downloaded the lastest Perl release from https://www.perl.org/get.html#win32 and have been reading the README.win32 to make sure I install it correctly.
As I need a compiler, I decided to use Gcc and dmake. I installed and can run them successfully so went back to installing Perl. As per instructions I tried running dmake in the win32 subdirectory in the Perl download folder. Before this I edited makefile.mk, where these variables are uncommented from the Build configuration section:
INST_DRV/INST_TOP (left as is)
INST_VER *= \5.26.0
USE_MULTI *= define
USE_ITHREADS *= define
USE_IMP_SYS *= define
USE_LARGE_FILES *= define
USE_64_BIT_INT *= define
USE_LONG_DOUBLE *= define
DEFAULT_INC_EXCLUDES_DOT *= define
CCTYPE = GCC
GCCWRAPV *=define
CCHOME *= C:\MinGW
(nothing else changed after this)
When I run dmake in the directory, it quickly comes to this error:
gcc -c -I.\include -I. -I.. -DWIN32 -DPERLDLL -DPERL_CORE -s -O2 -
D__USE_MINGW_ANSI_STDIO -fwrapv -fno-strict-aliasing
-DPERL_EXTERNAL_GLOB -DPERL_IS_MINIPERL -omini\toke.o ..\toke.c
In file included from ..\perl.h:3220:0,
from ..\toke.c:40:
./win32.h:417:13: error: conflicting types for 'mkstemp'
extern int mkstemp(const char *path);
^~~~~~~
In file included from ..\perl.h:790:0,
from ..\toke.c:40:
c:\mingw\include\stdlib.h:809:30: note: previous definition of 'mkstemp' was here
__cdecl __MINGW_NOTHROW int mkstemp (char *__filename_template)
^~~~~~~
In file included from ..\toke.c:40:0:
..\toke.c: In function 'Perl_filter_add':
..\perl.h:1756:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
#define PTR2nat(p) (PTRV)(p) /* pointer to integer of PTRSIZE */
^
..\perl.h:1769:28: note: in expansion of macro 'PTR2nat'
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^~~~~~~
..\toke.c:4397:21: note: in expansion of macro 'FPTR2DPTR'
IoANY(datasv) = FPTR2DPTR(void *, funcp); /* stash funcp into spare field */
^~~~~~~~~
..\perl.h:1769:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^
..\toke.c:4397:21: note: in expansion of macro 'FPTR2DPTR'
IoANY(datasv) = FPTR2DPTR(void *, funcp); /* stash funcp into spare field */
^~~~~~~~~
..\toke.c: In function 'Perl_filter_del':
..\perl.h:1756:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
#define PTR2nat(p) (PTRV)(p) /* pointer to integer of PTRSIZE */
^
..\perl.h:1769:28: note: in expansion of macro 'PTR2nat'
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^~~~~~~
..\toke.c:4463:26: note: in expansion of macro 'FPTR2DPTR'
if (IoANY(datasv) == FPTR2DPTR(void *, funcp)) {
^~~~~~~~~
..\perl.h:1769:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
^
..\toke.c:4463:26: note: in expansion of macro 'FPTR2DPTR'
if (IoANY(datasv) == FPTR2DPTR(void *, funcp)) {
^~~~~~~~~
..\toke.c: In function 'Perl_filter_read':
..\perl.h:1756:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
#define PTR2nat(p) (PTRV)(p) /* pointer to integer of PTRSIZE */
^
..\perl.h:1768:28: note: in expansion of macro 'PTR2nat'
#define DPTR2FPTR(t,p) ((t)PTR2nat(p)) /* data pointer to function pointer */
^~~~~~~
..\toke.c:4554:13: note: in expansion of macro 'DPTR2FPTR'
funcp = DPTR2FPTR(filter_t, IoANY(datasv));
^~~~~~~~~
..\perl.h:1768:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#define DPTR2FPTR(t,p) ((t)PTR2nat(p)) /* data pointer to function pointer */
^
..\toke.c:4554:13: note: in expansion of macro 'DPTR2FPTR'
funcp = DPTR2FPTR(filter_t, IoANY(datasv));
^~~~~~~~~
In file included from ..\perl.h:5644:0,
from ..\toke.c:40:
..\toke.c: In function 'S_pending_ident':
..\perl.h:1734:26: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
# define INT2PTR(any,d) (any)(d)
^
..\embed.h:427:59: note: in definition of macro 'newUNOP_AUX'
#define newUNOP_AUX(a,b,c,d) Perl_newUNOP_AUX(aTHX_ a,b,c,d)
^
..\toke.c:8912:37: note: in expansion of macro 'INT2PTR'
INT2PTR(UNOP_AUX_item *,
^~~~~~~
I get a bunch of warnings beforehand about casting from pointers to integers of different sizes, but this is the bit where it stops and produces an error. Am I missing something obvious? I haven't done this for a while, so I'm hoping it is a silly user error on my part! Thanks.
Try obtaining the MinGW source packages, and installing using makepkg-mingw to build them.
Most if not all have patches applied to customize (or fix) them for the MSYS2/MinGW environment.
Stock source downloaded from its author may not compile directly in that environment the way it would on Linux, or OS X using "configure" and "make".
Instructions are available, and there may be other similar instructions out there associated with Arch Linux.

GCC - display preprocessed value during preprocessing

Is there a way to make GCC display the value of some preprocessed value during preprocessing? In particular, if I run the equivalent of:
gcc input.c -E >/dev/null
Is there a way to obtain the actual value of an expanded macro? Consider this example:
#if defined(A)
#define B bar
#else
#define B foo
#endif
#define XSTR(x) STR(x)
#define STR(x) #x
int main() {
#pragma message "B is " XSTR(B)
#error DIE
B a = 2;
return 0;
}
I would like to find out that B is foo in this case.
In my actual setup, I do not have access to the entirely preprocessed file, and I cannot remove the -E flag.
Rationale: I have a complex file setup with lots of syntax errors due to incorrectly defined macros, and the fastest way to debug it would be to use this #pragma/#error combination to find out the actual value, stop compilation, manually fix it, and run GCC again to find out where the next error will occur.

gcc/ld: Allow Code Placement And Removal of Unused Functions

I am trying to allow specifying the location of particular symbols in my output binary without giving up the garbage collection feature of ld. For example: if I have in MyInclude.h
#ifndef MY_INCLUDE_H_
#define MY_INCLUDE_H_
void CalledFunc(void);
void UncalledFunc(void);
#endif
and a main program:
#include "MyInclude.h"
int main(void)
{
CalledFunc();
return 0;
}
compiling with gcc with ffunction-sections -fdata-sections and linking with --gc-sections shows in the map file that .text.UncalledFunc has been removed.
I now have a need where I have to place certain functions in different sections. In this example if UncalledFunc() did happen to be called, I want it to be in a special section. I have a linker parameter file that looks something like:
MEMORY
{
FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 512K
}
SECTIONS
{
.text.myregion ORIGIN(FLASH):
{
*(.text.myregion)
*(.text.myregion*)
} >FLASH
ASSERT ( . <= 0x10010000, "Too much stuff in myregion!")
.text :
{
*(.text)
*(.text*)
} >FLASH
}
And UncalledFunc() and CalledFunc() defined as:
void CalledFunc(void) __attribute__ ((section (".text.myregion")))
{
/* ... */
}
void UncalledFunc(void) __attribute__ ((section (".text.myregion")))
{
/* ... */
}
In this case, it seems the function attribute overrides the per function section parameter sent to GCC. As such since both functions are in the same input section, they both appear in the output image. Is there a way to tell the linker to place UncalledFunc() in .text.myregion if it is called but still remove it if it is not? As shown above, myregion has limited space and it would optimal to not place anything there that wasn't necessary.
The compiler is just doing what it's told; you asked it to put that function in that section, so what else should it do?
The linker then sees all the functions in one section, and so garbage collection is not very helpful.
I've not tried this, but I would imagine that simply assigning different manual names to each function will solve the problem:
void CalledFunc(void) __attribute__ ((section (".text.myregion.CalledFunc")))
{
/* ... */
}
void UncalledFunc(void) __attribute__ ((section (".text.myregion.UncalledFunc")))
{
/* ... */
}
However, if that's a lot of typing (or if you use a macro to apply the attribute), then it might be better like this:
#define STRINGIFY(S) #S
#define TOSTRING(S) STRINGIFY(S)
#define NAME __FILE__ "." TOSTRING(__LINE__)
void CalledFunc(void) __attribute__ ((section (".text.myregion." NAME)))
{
/* ... */
}
That way you can do it with search-and-replace and still have each function have a unique section name. (It is necessary to use the macro because __LINE__ is an integer value, but we need a string here, and the # "stringify" operator is only available inside macros. The apparently pointless levels of indirection cause __LINE__ to be evaluated into the actual line number.)
It might be that the __FUNCTION__ macro works, but I'm not confident given that this is outside the function body.
If you use link time optimization, compiler should be able to remove unused functions, even if you put all of them into common section.
So keep modules (let's say include.c include.h test.c), but build like this:
gcc -c -Os -flto include.c -o include.o
gcc -c -Os -flto test.c -o test.o
gcc -flto -Os test.o include.o -o test
This will probably (depends on actual code) inline used function and remove unused one (unless you use attribute noinline.

How to suppress "warning: control reaches end of non-void function"

I have some PowerPC assembly code translated with a gcc cross compiler with this function:
uint32_t fill_cache(void)
{
__asm__ ("addi 3, 0, 0\n"); /* R3 = 0 */
/* More asm here modifying R3 and filling the cache lines. */
}
which, under the PowerPC EABI, returns the value computed in R3. When compiling I get
foo.c:105: warning: control reaches end of non-void function
Is there a way to teach gcc that a value is actually returned? Or is there a way to suppress the warning (without removing -Wall or adding -Wno-*)? I would like to very selectively suppress this warning for only this function in order to leave the general warning level as high as possible.
It is not an option to make this function return void since the value computed is required by the caller.
Solution 1: with diagnostic pragmas you can locally suppress certain diagnostic checks. The specific option (which also is implied by -Wall) that complains for no return in a non-void function is -Wreturn-type. So the specific code to suppress the warning is:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wreturn-type"
/* Your code here */
#pragma GCC diagnostic pop
You can find out which option is causing the warning by compiling with -fdiagnostics-show-option. It will simply append the option to the warning message.
Solution 2: define a register variable and put it in the desired register. Refer to the variable in an inline assembler template, with the resulting code:
uint32_t fill_cache(void)
{
register uint32_t cacheVal __asm__ ("r3");
__asm__ __volatile__ ("addi %0, 0, 0" : "=r" (cacheVal));
/* More code here */
return cacheVal;
}
The volatile modifier is to ensure that the instruction is not removed or in some other way affected undesirably by the optimization strategy.
Solution 2 is preferred for at least two reasons:
The value of a no returning non-void function is undefined as far as the standard is concerned.
There's no risk of suppressing (new) diagnostic warnings there was no intention to suppress in the first place.
Function could be declared as naked, in this case compiler would not generate prolog & epilog and would assume that programmer preserves all necessary registers and puts output value into correct register(s) before return.
uint32_t fill_cache(void) __attribute__((naked)); // Declaration
// attribute should be specified in declaration not in implementation
uint32_t fill_cache(void)
{
__asm__ ("addi 3, 0, 0\n"); /* R3 = 0 */
/* More asm here modifying R3 and filling the cache lines. */
}
A bit late but maybe someone will step in this as well :)
PS: For my best knowledge __asm__ as well as __volatile__ are std=c89 syntax. Practically there is not difference between __asm__ & asm in GNU GCC. But the modern approach is underscoreless style: asm volatile.
asm_language

Temporarily disable gcc warning on redefinition

I'm trying to make this work (in GCC 4.6) without barking at me.
#define FOO ""
#define BAR ""
#if ....
#define FOO "Foo, good sir"
#endif
#if ...
#define BAR "Bar, my lady"
#endif
....
#define EVERYTHING FOO BAR ...
I am going to have a lot of these. So doing it that way instead of:
#if ...
#define FOO "Foo"
#else
#define FOO ""
#endif
Saves a lot of code, and makes it more readable. The warning that I get is:
warning: "FOO" redefined [enabled by default]
Is there a way to disable this warning in the code for this particular section? I found Diagnostic Pragmas to disable certain warnings, but I'm not able to find which warning (in this list of Options to Request or Suppress Warnings) that needs to be disabled here.
Anyone know how to do this? Or a different way to avoid having to #else #define all of them to the empty string?
Try using #undef:
#define FOO ""
#if ....
#undef FOO
#define FOO "Foo, good sir"
#endif
This warning comes from file named "cccp.c" in gcc (as of 2.95 version; is this file from "Soviet Russia"?), and it can't be turned off. There is still no option to disable this warning individually even in git head, gcc/libcpp/macro.c file (line 2527 and line 2994 of the same file)
I'll cite sources a bit.
2525 /* Returns nonzero if a macro redefinition warning is required. */
2526 static bool
2527 warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node,
2528 const cpp_macro *macro2)
2529 {
...
2537 /* Suppress warnings for builtins that lack the NODE_WARN flag. */
..
2545 /* Redefinitions of conditional (context-sensitive) macros, on
2546 the other hand, must be allowed silently. */
...
2550 /* Redefinition of a macro is allowed if and only if the old and new
2551 definitions are the same. (6.10.3 paragraph 2). */
...
2561 /* Check parameter spellings. */
...
2566 /* Check the replacement text or tokens. */
...
2573 for (i = 0; i < macro1->count; i++)
2574 if (!_cpp_equiv_tokens (&macro1->exp.tokens[i], &macro2->exp.tokens[i]))
2575 return true;
So in your case warn_of_redefinition function will return true. And here is real usage:
2989 if (node->type == NT_MACRO)
2990 {
2991 if (CPP_OPTION (pfile, warn_unused_macros))
2992 _cpp_warn_if_unused_macro (pfile, node, NULL);
2993
2994 if (warn_of_redefinition (pfile, node, macro))
2995 {
2996 const int reason = (node->flags & NODE_BUILTIN)
2997 ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE;
2998 bool warned;
2999
3000 warned = cpp_pedwarning_with_line (pfile, reason,
3001 pfile->directive_line, 0,
3002 "\"%s\" redefined",
3003 NODE_NAME (node));
3004
3005 if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
3006 cpp_error_with_line (pfile, CPP_DL_NOTE,
3007 node->value.macro->line, 0,
3008 "this is the location of the previous definition");
3009 }
3010 }
So, there is no any specific option. And answer by Greg is good for this case, just undefine your empty string just before redefinition.
Or try using if else.
#if ...
# define FOO "Foo, doof sir"
#else
# define FOO ""
#endif

Resources