GCC/Cygwin and long longs. A bug?

Started by
7 comments, last by Shadowdancer 18 years, 3 months ago
Lo, I'm currently coding a sign extension function (and messing around with long long's a lot, since I'm working on a 32-bit platform). I believe my sign extension function works correctly - but GCC is really weird when it comes to printing them. For example, here's my sign extension function (QWORD is an unsigned long long)

QWORD SignExtend(QWORD value,DWORD highBit)
{
	if (((value >> highBit) & 1) == 1)
	{
		/* Set all bits higher than highBit to one */
		DWORD i=highBit+1;
		while (i < 32)
			value|=(1 << i++);

		value|=(0xFFFFFFFFULL << 32);
		printf("%#llX\n",value);
	}

	return value;
}


In theory, this should print a value above 4 billion (i.e. > 0xFFFFFFFF) but all that gets printed are the lower 32 bits. The GCC version I'm using is 3.4.4. What is wrong? I've also found general weirdness with printing long longs. For instance, I print one, and the next long long printed is zero. If I print them seperately, there's no problem. Should I submit a bug to the cygwin mailing list or gcc mailing list? Also, I'm currently compiling with -mno-cygwin. I don't know if that changes much. CloudNine [Edited by - CloudNine on January 3, 2006 5:50:43 AM]
Advertisement
That's weird..

Have you tried moving the ll type to the other side of the # modifier (it's supposed to and a 0x prefix to hexadecimal constants, right?), or removing it entirely? You may even want to check if it works for regular decimal values (%lld).
Have you tried sanity-checking GCC's printf type checker by sending a regular integer instead of a 64-bit one?

Otherwise you may just have to do a bit of digging in the source to find out what's happening, although you'd think something as basic as this should've been properly tested.
Yep, I've tried everything, and have -Wall on so printf arguments are checked. But no luck. It still prints out as if the argument were 32 bits.

I'll have to post to the cygiwn mailing list then?
Quote:Original post by CloudNine
I'll have to post to the cygiwn mailing list then?
Well, either that or step through it in a debugger.
Of course you may want to check other versions and distributions of GCC too, possibly even check out the official bug list to see if it's a known issue.

Quote:0xFFFFFFFFULL
Cute..
Tried it using gcc 3.3.4 for linux (using libc 2.3.4) and it performs correctly. I'm now assuming it's something wrong with the cygwin c library. I can't find the package for it in setup.exe, I'll search harder :)
This is a long standing problem with cygwin and long longs.

Essentially, long long is a gnu extension. It is present in the compiler, so the code compiles correctly, but long long is not present in the c standard library you are using, probably because it is the M$ C-runtime.

Try using "%I64X" or such MS-specific int64 extension instead of gnu-specific "%llX"
Quote:Original post by CloudNine
Tried it using gcc 3.3.4 for linux (using libc 2.3.4) and it performs correctly. I'm now assuming it's something wrong with the cygwin c library. I can't find the package for it in setup.exe, I'll search harder :)
Quote:Original post by CloudNine
Also, I'm currently compiling with -mno-cygwin. I don't know if that changes much.
I just noticed that you're compiling in the mingw "mode", which IIRC uses Microsoft's CRT directly instead of GNU's implementation. And since VC doesn't support C99 long longs you'll probably have to use "%I64X" instead.

edit: Beaten..
Ah, that solves it. Sorry to trouble you guys.

gcc still complains about that format specifier tho, but it works :)
Quote:Original post by etothex
Essentially, long long is a gnu extension. It is present in the compiler, so the code compiles correctly, but long long is not present in the c standard library you are using, probably because it is the M$ C-runtime.


AFAIK, (unsigned) long long is standard C99.

This topic is closed to new replies.

Advertisement