What Does the Gcc Warning "Project Parameter Passing for X Changed in Gcc 7.1" Mean

What does the gcc warning project parameter passing for X changed in GCC 7.1 mean?

That warning is telling you that there was a subtle ABI change (actually a conformance fix) between 6 and 7.1, such that libraries built with 6.x or earlier may not work properly when called from code built with 7.x (and vice-versa). As long as all your C++ code is built with GCC 7.1 or later, you can safely ignore this warning. To disable it, pass -Wno-psabi to the compiler.

For more details on the context of the change, see the GCC 7 changelog, and the associated bug.

What exactly does GCC's -Wpsabi option do? What are the implications of supressing it?

You only need to worry about ABIs when you are crossing library boundaries. Within your own applications/libraries the ABI doesn't really matter as presumably all your object files are compiled with the same compiler version and switches.

If you have a library compiled with ABI1 and an application compiled with ABI2 then the application will crash when it tries to call functions from the library as it wont pass the arguments correctly. To fix the crash you would need to recompile the library (and any other libraries it depends on) with ABI2.

In your specific case as long as you compile nlohmann with the same compiler version as your application (or are just using nlohmann as a header) then you don't need to worry about the ABI change.

Globally suppressing the warning seems to be a dangerous option as it will prevent you from seeing any future ABI issues. A better option would be to use #pragma to disable the warning just for the functions in question, e.g.:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wno-psabi"
void foo()
{
}
#pragma GCC diagnostic pop

enabling differing levels of indirection warning/error in gcc

As was pointed out to me by several folks in the comments (thanks all), even differing levels of indirection aren't considered when it comes to void*. I verified this in other compilers. So the answer to my actual question, best I can tell, is that there is no warning or error that can be enabled, regardless of compiler.

That said, if the void* actually points to a concrete type, it is relatively painless, even in very large solutions to clean this up. I went with forward-declaring the types:

struct config_o;
typedef config_o* config_h;
//removed typedef void* config_h;

I was able to clean up about 40 handle types in 200,000 lines of code in significantly less than 8 hours. Found (and fixed) several serious bugs while I was at it, which consumed the majority of the time.

How to disable GCC warnings for a few lines of code

It appears this can be done. I'm unable to determine the version of GCC that it was added, but it was sometime before June 2010.

Here's an example:

#pragma GCC diagnostic error "-Wuninitialized"
foo(a); /* error is given for this one */

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
foo(b); /* no diagnostic for this one */
#pragma GCC diagnostic pop

foo(c); /* error is given for this one */
#pragma GCC diagnostic pop

foo(d); /* depends on command line options */

using -march switch for gcc does not make a difference in terms of run-time speed

I think you should be specifying -march=native as part of LDFLAGS as well, so -flto is targeting the same machine.

But it seems your code-gen is respecting your specified arch since you say -march=alderlake make code that crashed with SIGILL, probably on an AVX encoding of a vector instruction.


It's quite possible that -mtune=generic makes the same tuning decisions as -march=native, and that there's nothing that benefits from anything more than SSE2. Your CPU supports SSE4.2 and popcnt, but baseline for x86-64 is already SSE2, same vector width just missing some instructions, especially for dword and qword element sizes (like packed min/max).

GCC/clang can't auto-vectorize search loops (only loops where the trip-count is known at runtime before the first iteration), so inputStr.find_first_of either compiles to a one-byte-at-a-time search, or calls memchr which only benefits from SSE2 anyway, but can dynamic dispatch based on CPU features since it's in a shared library.

(Glibc overloads the dynamic linking process with a "resolver" function that decides which implementation of memchr is best on the current machine, either SSE2 or AVX2. The both versions are hand-written asm, for example the SSE2 version's source. A few functions like strstr have SSE4.2 versions that you CPU can take advantage of, but this choice doesn't depend on -march compile-time settings, purely run-time dynamic linker + glibc.)


If you want to see where your program is spending most of its time, use perf record ./a.out / perf report -Mintel (the default is AT&T syntax disassembly; I prefer Intel).

If it's in library functions, different tuning options and new instructions available probably aren't helping your main code. If it's in your program proper, not libs, then apparently the baseline instruction-set for x86-64 and the "generic" tuning options are fine, or GCC doesn't know how to get any use out of SSSE3 / SSE4.x for your code.

I didn't look much at what your code is doing to see what manual vectorization might be possible.

Son of GCC conversion warning when assigning to a bitfield

Without any answers for me to accept after a day, I'll summarize the discoveries from the comments.

  • @Artyer discovered that casting the variable to a Boolean fixes the problem. This fixes the tactical problem but does not solve the more general problem (e.g. z & 0xf).

    num->b = (5U << 1) | (_Bool)(x & 1);
  • @M.M independently discovered what I assume results in the same effect (conversion to Boolean). Using !! makes the problem go away. Again, this fixes the tactical problem but does not solve the more general problem (e.g. z & 0xf).

    num->b = (5U << 1) | !!(x & 1);
  • I discovered, while investigating the above solutions, that storing the "constant" side of the expression into a variable works around the problem generally.

    unsigned int z = 5U;
    num->b = (z << 1) | (x & 1);
  • @yugr believes that this is a bug. Bug 95213 opened with gcc to track this.

What does the gcc accent character mean/do?

The backticks here are for the shell, not for gcc. The shell executes the command inside the backticks and substitutes the output of the command. Presumably the msql_config command with those options produces the options you should pass to gcc.



Related Topics



Leave a reply



Submit