Compilation Error (pre-C99 compilers)

Hi, i’m trying to compile SWI from source. However, i get the follogin error (that could be easily fixed…) using make:

/home/dazzolin/swipl-devel/src/os/pl-utf8.c: In function ‘_PL__utf8_code_point’:
/home/dazzolin/swipl-devel/src/os/pl-utf8.c:80:3: error: ‘for’ loop initial declarations are only allowed in C99 mode
for (int k = 0; k < n; ++k)
^
/home/dazzolin/swipl-devel/src/os/pl-utf8.c:80:3: note: use option -std=c99 or -std=gnu99 to compile your code

Furthermore, there are some warnings (they may not be significant but I list them anyway)

/home/dazzolin/swipl-devel/src/pl-wam.c: In function ‘PL_next_solution’:
/home/dazzolin/swipl-devel/src/pl-vmi.c:5181:8: warning: ‘args’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   Word args;
        ^
/home/dazzolin/swipl-devel/src/pl-vmi.c:5515:8: warning: ‘arity’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   { if ( arity > MAXARITY )
        ^
/home/dazzolin/swipl-devel/src/pl-vmi.c:5180:7: note: ‘arity’ was declared here
   int arity;
       ^
In file included from /home/dazzolin/swipl-devel/src/pl-incl.h:2537:0,
                 from /home/dazzolin/swipl-devel/src/pl-wam.c:39:
/home/dazzolin/swipl-devel/src/pl-ldpass.h:75:51: warning: ‘functor’ may be used uninitialized in this function [-Wmaybe-uninitialized]
 #define resolveProcedure(f,m) resolveProcedure__LD(f, m PASS_LD)
                                                   ^
In file included from /home/dazzolin/swipl-devel/src/pl-wam.c:3073:0:
/home/dazzolin/swipl-devel/src/pl-vmi.c:5179:13: note: ‘functor’ was declared here
   functor_t functor;
/home/dazzolin/swipl-devel/src/pl-gmp.c: In function ‘mpz_fdiv.isra.9’:
/home/dazzolin/swipl-devel/src/pl-gmp.c:1543:17: warning: ‘r_mode’ may be used uninitialized in this function [-Wmaybe-uninitialized]
       fesetround(r_mode);
In file included from /home/dazzolin/swipl-devel/src/pl-thread.h:39:0,
                 from /home/dazzolin/swipl-devel/src/pl-incl.h:2529,
                 from /home/dazzolin/swipl-devel/src/pl-tabling.c:37:
/home/dazzolin/swipl-devel/src/pl-tabling.c: In function ‘simplify_delay_set’:
/home/dazzolin/swipl-devel/src/os/pl-buffer.h:142:39: warning: value computed is not used [-Wunused-value]
  ((b)->top -= sizeof(type), (type*)(b)->top)
                                       ^
/home/dazzolin/swipl-devel/src/pl-tabling.c:1029:7: note: in expansion of macro ‘popBufferP’
       popBufferP(&di->delay_sets, delay_set);
                 ^

Its 2021, so C99 is 22 years among us :slight_smile: Which ancient compiler are you using?

Modern compilers are smarter in figuring out what is really uninitialized. I try to minimize the number of unneeded initializations to silence the compiler because such initializations hide warnings that can be useful and harm performance. You can fairly safely ignore these.

If you want/need to stick with an old compiler you can simply move int k outside the loop.

Yeah, indeed I use GCC 4.8.4 (June 2015) but i’m on a cluster i do not maintain so I cannot directly update packages (unless I install them in my home…). Moving the declaration of the variable outside the loop is completely fine for me.

:frowning: I think older GCC versions can use C99 if you give it some flags. Only recently I started to use C99 and give up compatibility with older compilers. We must move forward one day :slight_smile:

1 Like

Hi

I’m trying to compile swipl on an InMotion virtual private server (CENTOS 7.9). I ran into the “loop initial declarations are only allowed in C99 mode” problem :

/home/n042045/swipl-devel/src/pl-wam.c: In function ‘updateAlerted’:
/home/n042045/swipl-devel/src/pl-builtin.h:377:21: error: ‘for’ loop initial declarations are only allowed in C99 mode
#define WITH_LD(ld) for (PL_local_data_t *__PL_ld = (ld), *__loopctr = NULL; !__loopctr; __loopctr++)
^
Sure enough the GCC version installed on the VPS was old (4.8.5), so I downloaded and (eventually) compiled 10.3.0 :

gcc --version
gcc (GCC) 10.3.0

Same problem. It seems the swipl build is not using my 10.3.0 GCC even though gcc --version reports the right version. No doubt this problem reflects my ignorance of Linux, but help!

PS I tried to use snap but

snap install swi-prolog
error: system does not fully support snapd: cannot mount squashfs image
using “squashfs”: mount: /tmp/sanity-squashfs-183028853: failed to setup
loop device: No such file or directory

which is explained by:

It is a bit of a challenge to build SWI-Prolog on such old stuff. It can be done though. See SWI-Prolog Continuous integration status for evidence. The specs for the build are at docker-swipl-linux-ci/centos/7 at master · SWI-Prolog/docker-swipl-linux-ci · GitHub. The vital one of overcome the above problem is to use

CFLAGS=-std=gnu99 cmake ...

Hi Jan

Thanks for that. Your “on such old stuff” tells me all I need to know. I’ll find a more suitable VPS, maybe even one with swipl available :slight_smile:

Cheers

Mike

I’d look for one based on Ubuntu so you can use the PPA builds.

Great advice Jan. I found a local provider running Ubuntu. PPA worked perfectly.

2 posts were split to a new topic: Failed to compile SSL (HAVE_EVP_MD_CTX_FREE)

Is it OK to use C99 language features for PRs to SWI-Prolog source code or the packages?

e.g.

for (int i = ... )
bool b = true;
// one-line comment
int vals[n];

etc.

Currently SWI-Prolog requires C11 to compile. The way we now handle the LD (Local Data) structure is based on the C11 Generics construct, thanks to @dmchurch. Declaring the loop variable in a for is surely fine. Using bool is possibly a bit dubious considering how several parts of the code handles booleans. Would be good to review use of booleans and where possible move to use the new standards. One of the problems is that we have macros for true and false. With @dmchurch we considered renaming these to ison and isoff, which have the nice property to have the same number of characters :slight_smile: . It should be fine for local usage though.

I never much liked extensive comments inside functions. Neither on predicates. Please limit to small remarks well separated from the code in the right margin. If there is something complicated to tell, use see (*) and put an extensive comment block above the code. As a rule of thumb though, if code needs complicated comments it is wrong :slight_smile:

Using dynamic arrays (finally no longer just a gcc extension?) is fine, but only if there is a proper guarantee it won’t overflow the stack. Most code that require an array of dynamic size predefine a small local array and a pointer to this array. If the data is too large we make the pointer use a malloc’ed array and free at the end. That is a bit of code, but keeps stack usage low, avoids stressing malloc (and fragmentation) and keeps the promise that there are no limits on data size.

1 Like