6

I'm trying to hunt down a problem using complex literals when compiling with GCC. Consider the following

#include <stdio.h>
#include <complex.h>

int main(void)
{
    double complex z = CMPLX(0.0, -1.0);
    printf("z = %.1f%+.1fi\n", creal(z), cimag(z));
    return 0;
}

(slightly modified from the reference page). If I compile with Clang, it works as expected. However, if I use GCC I get an undefined reference error

gcc -std=c11 mwe.c
mwe.c: 6:24 warning: implicit declaration of function 'CMPLX' ...
mwe.c:(...) undefined reference to `CMPLX'

I have tried this with GCC 4.7 and 7.2 on Linux and GCC 9 on MacOS. The error messages change, but the net result remains the same. Reviewing the reference for CMPLX, this should be valid C11. Based on this answer and this post, it appears like GCC accepted this construct before.

My bottom line question is: Why can't I use CMPLX with GCC?

Keith Prussing
  • 803
  • 8
  • 19
  • *The error messages change, but the net result remains the same* - change how? – Eugene Sh. Nov 19 '19 at 15:38
  • `CMPLX` certainly appears to be valid in C11: [**7.3.9.3 The CMPLX macros**](https://port70.net/~nsz/c/c11/n1570.html#7.3.9.3) – Andrew Henle Nov 19 '19 at 15:41
  • 1
    Can't reproduce on neither GCC versions on https://wandbox.org/ – Eugene Sh. Nov 19 '19 at 15:42
  • @eugene Trivial error formatting differences. Two lines versus one line, including the flag that triggered it or not. – Keith Prussing Nov 19 '19 at 15:42
  • Is your `gcc` command aliased or anything other than directly executing the proper `gcc` executable itself? The fact that whatever your `gcc` command is accepts the `-std=c11` argument then doesn't properly process `CMPLX` is strange. – Andrew Henle Nov 19 '19 at 15:44
  • On the Mac `gcc` is an symlink to the MacPorts gcc-p (`gcc-mp-9`). On Linux, it's gcc 4.7 and 7.2 installed by the system admins. – Keith Prussing Nov 19 '19 at 15:46
  • The version of `gcc` may be defaulting to an earlier version than `c11`. Please post your compile statement. Does it have a option: `-std=c11` (or later version of C)? – user3629249 Nov 19 '19 at 17:48
  • Yes. See the example in the question. If GCC is not respecting the `std=c11` flag, that is problematic. – Keith Prussing Nov 19 '19 at 17:52
  • @AndrewHenle, My system says: "Warning: Potential Security Risk Ahead" about the web page you linked to. Suggest: [CMPLX](https://en.cppreference.com/w/c/numeric/complex/CMPLX) – user3629249 Nov 19 '19 at 17:58
  • @user3629249 cppreference.com is nowhere near as authoritative as a copy of the draft C11 standard that was actually adopted as the C11 standard itself. If you can find another HTML copy of the last C11 draft standard online, I'll link that. – Andrew Henle Nov 19 '19 at 18:00
  • I'm on ubuntu linux with GCC version: "gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)" and the code compiles/links with no problems. Suggest using a recent version of `gcc` – user3629249 Nov 19 '19 at 18:01

1 Answers1

0

It appears like this is caused by a header/library disconnect on the systems I have. Compiling with the -save-temps flag, it appears GCC uses the system header for complex.h. This means the selected Xcode SDK's usr/include/complex.h on MacOS and /usr/include/complex.h on Linux. On MacOS, the CMPLX macro is only defined when using Clang. The Linux I have is RHEL 6 meaning the header is aimed at GCC 3 which did not have CMPLX. Based on the discussion on this bug report, it looks like making sure the macro is defined is not up to GCC.

The short answer is: The compiler/platform combination doesn't support it. Use the native compiler or update the system.

Keith Prussing
  • 803
  • 8
  • 19