SettRaziel / wrf_archlinux

scripts and files to run your own wrf with archlinux
19 stars 6 forks source link

GCC 14 leads to compile errors in WRF/WPS compilation #135

Open SettRaziel opened 4 months ago

SettRaziel commented 4 months ago

With the update to gcc 14 several new changes regarding compile flags were done. These lead to a more restrict error handling since several flags that would only lead to warnings now lead to compile errors:

Looking on the changes with gcc 14 it seems they have change the flag: GCC 14

Implicit function declarations (-Werror=implicit-function-declaration) It is no longer possible to call a function that has not been declared. In general, the solution is to include a header file with an appropriate function prototype. Note that GCC will perform further type checks based on the function prototype, which can reveal further type errors that require additional changes.

For well-known functions declared in standard headers, GCC provides fix-it hints with the appropriate #include directives:

error: implicit declaration of function ‘strlen’ [-Wimplicit-function-declaration]
    5 |   return strlen (s);
      |          ^~~~~~
note: include ‘<string.h>’ or provide a declaration of ‘strlen’
  +++ |+#include <string.h>
    1 |

When compiling the wrf model now these new restriction lead to these compile errors, e.g.

gcc  -I. -w -O3 -c   -DDM_PARALLEL -DLANDREAD_STUB=1 -DMAX_HISTORY=25 -DNMM_CORE=0   -c get_region_center.c
get_region_center.c: In function ‘get_region_center_’:
get_region_center.c:40:3: error: implicit declaration of function ‘memcpy’ [-Wimplicit-function-declaration]
   40 |   memcpy(MemoryOrder,MemoryOrderIn,strlen1);
      |   ^~~~~~

To turn them back to warnings the given compile flag needs to be set before compiling the code Warning Options:

-Wimplicit-function-declaration -Werror-implicit-function-declaration Give a warning (or error) whenever a function is used before being declared. The form -Wno-error-implicit-function-declaration is not supported. This warning is enabled by -Wall (as a warning, not an error).

SettRaziel commented 4 months ago

Changes regarding this error are resolved with WRF-1823. But the compile process for 4.6 does run in other errors. These are also related to GCC 14 changes (in my opinion):

Type checking on pointer types (-Werror=incompatible-pointer-types) GCC no longer allows implicitly casting all pointer types to all other pointer types. This behavior is now restricted to the void * type and its qualified variations.

To fix compilation errors resulting from that, you can add the appropriate casts, and maybe consider using void in more places (particularly for old programs that predate the introduction of void into the C language).

Programs that do not carefully track pointer types are likely to contain aliasing violations, so consider building with -fno-strict-aliasing. (Whether casts are written manually or performed by GCC automatically does not make a difference in terms of strict aliasing violations.)

A frequent source of incompatible function pointer types involves callback functions that have more specific argument types (or less specific return types) than the function pointer they are assigned to. For example, old code which attempts to sort an array of strings might look like this:


#include <stddef.h>
#include <stdlib.h>
#include <string.h>

int compare (char a, char b) { return strcmp (a, b); }

void sort (char *array, size_t length) { qsort (array, length, sizeof (array), compare); }

I now get around 80 errors like this:
c_code.c: In Funktion »rsl_litepack«: c_code.c:487:27: Fehler: Übergabe des Arguments 1 von »f_packlint« von inkompatiblem Zeigertyp [-Wincompatible-pointer-types] 487 F_PACK_LINT ( buf, p+yp_curs, imemord, &js, &je, &ks, &ke, &is, &ie, ^~~
char *

In Datei, eingebunden von c_code.c:31: rsl_lite.h:200:25: Anmerkung: »long int « erwartet, aber Argument hat Typ »char « 200 | void F_PACK_LINT (long inbuf, long outbuf, int memorder, int js, int je, int ks, int ke, int is, int ie, int jms, int jme, int kms, int kme, int ims, int ime, int curs); | ~~^~~~~


The error is an incompatible pointer type, here long int* instead of char*.