Complex values handling in Clang

Hi All,

Complex values stored in variable value mismatches if program compiled clang and gcc.

Below is the sample program printing byte by byte stored “complex long long int” value,

int main()
{
_Complex unsigned long long int lli_val= (5668231682443686620ULL + 7618395480654047911ULL*extension 1i);
// _Complex long double ld_val = (5668231682443686620ULL + 7618395480654047911ULL*extension 1i);
int size = sizeof(lli_val);
int index = 0;
printf(“long long int val:\n”);
while (size != index)
{
unsigned char cval = (unsigned char)(((unsigned char)&lli_val) + index);
printf("%x", cval);
index++;
}
}

Outputs of clang compiled, gcc compiled values are:
For Clang,
long long int val:
dcb2ab00000a76ad35e0000
For GCC,
long long int val:
dcb2ab0af9aa94ea76ad35e53fab969

Similar behaviour observed for “_Complex float, _Complex double, _Complex long double” types.

Complex values in clang are not handled in similar to GCC, Could someone comment about it.

-rajesh

Hi all,

Could someone comment about it.

Thanks,
Rajesh

_Complex integer types are a GCC extension (the standard specifies only float _Complex, double _Complex and long double _Complex. Apparently clang's support for this GCC extension doesn't perfectly match GCC. I suspect that clang and GCC differ in arithmetic promotion rank here; clang "promotes" the unsigned long long literals to int _Complex (which truncates them), whereas GCC promotes both to unsigned long long _Complex. I haven't actually dug into the issue at all, however.

A couple of work-arounds seem to be available:

  unsigned long long int _Complex lli_val = (unsigned long long int _Complex){5668231682443686620ULL, 7618395480654047911ULL};

  unsigned long long int _Complex lli_val;
  __real__ lli_val = 5668231682443686620ULL;
  __imag__ lli_val = 7618395480654047911ULL;

I believe that both of these will work with recent GCCs as well.

- Steve

From: "Stephen Canon" <scanon@apple.com>
To: "rajesh viswabramana" <viswabramana.rajesh@gmail.com>
Cc: cfe-dev@cs.uiuc.edu
Sent: Friday, February 1, 2013 9:32:00 AM
Subject: Re: [cfe-dev] Complex values handling in Clang

_Complex integer types are a GCC extension (the standard specifies
only float _Complex, double _Complex and long double _Complex.
Apparently clang's support for this GCC extension doesn't perfectly
match GCC. I suspect that clang and GCC differ in arithmetic
promotion rank here; clang "promotes" the unsigned long long
literals to int _Complex (which truncates them), whereas GCC
promotes both to unsigned long long _Complex. I haven't actually
dug into the issue at all, however.

Did Bill just fix this in r174181?

-Hal

Certainly sounds like it from his description.