limits.h question

M

Mark Bruno

Hey, I'm learning about the limits header, and I don't understand one
snippit of code. If I code:

#include <limits.h>
#include <stdio.h>
int main()
{
printf("Smallest signed long long: %lld\n", LLONG_MIN);
return 0;
}
I get the output:
Smallest signed long long: 0

Why is this? I even check in my limits.h file, where I see:
#define LLONG_MIN 0x8000000000000000 /*minimum signed __int64 value */

Why won't it print the limit?
 
M

Mark Bruno

By the way...this might be off topic, but if i code the same thing in c++
with cout << it works ok...weird
 
M

Martin Ambuhl

Mark said:
Hey, I'm learning about the limits header, and I don't understand one
snippit of code. If I code:

#include <limits.h>
#include <stdio.h>
int main()
{
printf("Smallest signed long long: %lld\n", LLONG_MIN);
return 0;
}
I get the output:
Smallest signed long long: 0

Why is this? I even check in my limits.h file, where I see:
#define LLONG_MIN 0x8000000000000000 /*minimum signed __int64 value */

Why won't it print the limit?

It would seem that you are using a <limits.h> not appropriate for your
compiler. Make sure that you don't have a mismatch. For comparison, I get
for my implementation:

#include <limits.h>
#include <stdio.h>
int main(void)
{
printf("Smallest signed long long: %lld\n", LLONG_MIN);
printf("Smallest signed long: %ld\n", LONG_MIN);
printf("Smallest signed int: %d\n", INT_MIN);
printf("Smallest signed short: %hd\n", SHRT_MIN);
printf("Smallest signed char: %d\n", SCHAR_MIN);
printf("Largest signed long long: %lld\n", LLONG_MAX);
printf("Largest unsigned long long: %llu\n", ULLONG_MAX);
printf("Largest signed long: %ld\n", LONG_MAX);
printf("Largest unsigned long: %lu\n", ULONG_MAX);
printf("Largest signed int: %d\n", INT_MAX);
printf("Largest unsigned int: %u\n", UINT_MAX);
printf("Largest signed short: %hd\n", SHRT_MAX);
printf("Largest unsigned short: %hu\n", USHRT_MAX);
printf("Largest signed char: %d\n", SCHAR_MAX);
printf("Largest unsigned char: %u\n", UCHAR_MAX);
return 0;
}



Smallest signed long long: -9223372036854775808
Smallest signed long: -2147483648
Smallest signed int: -2147483648
Smallest signed short: -32768
Smallest signed char: -128
Largest signed long long: 9223372036854775807
Largest unsigned long long: 18446744073709551615
Largest signed long: 2147483647
Largest unsigned long: 4294967295
Largest signed int: 2147483647
Largest unsigned int: 4294967295
Largest signed short: 32767
Largest unsigned short: 65535
Largest signed char: 127
Largest unsigned char: 255
 
M

Mark Bruno

I'm using MS Visual C++ 7.1 (.net 2003), with all the appropriate headers.
Anyone with MSVC++7.1 out there who can vouch for this bug?
 
M

Mark Bruno

I think this stems from VC++'s non C99 compliance, so some long long
features are implemented, but some (such as %lld in printf and scanf)
aren't.
Mark Bruno said:
I'm using MS Visual C++ 7.1 (.net 2003), with all the appropriate headers.
Anyone with MSVC++7.1 out there who can vouch for this bug?
value
 
K

Kevin Goodsell

Mark said:
I think this stems from VC++'s non C99 compliance, so some long long
features are implemented, but some (such as %lld in printf and scanf)
aren't.

Please stop top-posting. It's rude.

My understanding is that Microsoft has not made, and has no interest in
making their compiler C99-compliant.

-Kevin
 
K

Kevin Goodsell

<OT>
I may be wrong, but I think that on Windows systems, printf is
implemented in msvc.dll (along with most if not all of the C standard
library). This is probably where the problem lies. You could check
whether there's an updated version with proper C99 support.

I tried a little test:

$ gcc -v
Reading specs from /usr/lib/gcc-lib/i686-pc-cygwin/3.3.1/specs
Configured with: /GCC/gcc-3.3.1-3/configure --with-gcc --with-gnu-ld
--with-gnu-as --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc
--libdir=/usr/lib --libexecdir=/usr/sbin --mandir=/usr/share/man
--infodir=/usr/share/info
--enable-languages=c,ada,c++,f77,pascal,java,objc --enable-libgcj
--enable-threads=posix --with-system-zlib --enable-nls
--without-included-gettext --enable-interpreter --enable-sjlj-exceptions
--disable-version-specific-runtime-libs --enable-shared
--disable-win32-registry --enable-java-gc=boehm
--disable-hash-synchronization --verbose --target=i686-pc-cygwin
--host=i686-pc-cygwin --build=i686-pc-cygwin
Thread model: posix
gcc version 3.3.1 (cygming special)


$ cat fun.c
#include <stdio.h>
#include <limits.h>

int main(void)
{
printf("LLONG_MAX: %lld\n", LLONG_MAX);
printf("LLONG_MIN: %lld\n", LLONG_MIN);

return 0;
}


$ gcc -W -Wall -std=c99 -pedantic-errors fun.c -o fun.exe


$ ./fun
LLONG_MAX: 9223372036854775807
LLONG_MIN: -9223372036854775808


$ gcc -W -Wall -std=c99 -pedantic-errors -mno-cygwin fun.c -o fun.exe


$ ./fun
LLONG_MAX: -1
LLONG_MIN: 0


When compiled with -mno-cygwin (which forces gcc to link against the
normal Windows libraries instead of the Cygwin unix-like libraries) I
see the same thing you do, probably because it's using the exact same
library (msvc.dll).
</OT>


-Kevin
 
K

Kevin Goodsell

Kevin said:
<OT>
I may be wrong, but I think that on Windows systems, printf is
implemented in msvc.dll

I think that should have been msvcrt.dll.

-Kevin
 
K

Keith Thompson

Mark Bruno said:
Hey, I'm learning about the limits header, and I don't understand one
snippit of code. If I code:

#include <limits.h>
#include <stdio.h>
int main()
{
printf("Smallest signed long long: %lld\n", LLONG_MIN);
return 0;
}
I get the output:
Smallest signed long long: 0

Why is this? I even check in my limits.h file, where I see:
#define LLONG_MIN 0x8000000000000000 /*minimum signed __int64 value */

Why won't it print the limit?

I don't believe 0x8000000000000000 is a legal definition for
LLONG_MIN, even if it happens to have the same bit pattern.
(But I suspect the real problem is that your printf() either
doesn't implement %lld, or doesn't implement it correctly.)
 
A

August Derleth

What's top posting? How do I stop it?

You just top-posted.

Here's an example of why you shouldn't do it.

A: It's self-explanatory.
Q: Why is it rude?
A: It's posting your reply above the post it's in response to.
Q: What is top-posting?

You don't do it by doing like I'm doing now: Put your reply below what you
are quoting. Snipping what you aren't responding to is also nice.
 
S

Servé Lau

Mark Bruno said:
Hey, I'm learning about the limits header, and I don't understand one
snippit of code. If I code:

#include <limits.h>
#include <stdio.h>
int main()
{
printf("Smallest signed long long: %lld\n", LLONG_MIN);
return 0;
}
I get the output:
Smallest signed long long: 0

Why is this? I even check in my limits.h file, where I see:
#define LLONG_MIN 0x8000000000000000 /*minimum signed __int64 value */

Why won't it print the limit?

I have VC7.1 too and I'm seeing the same.
I guess you can't rely on VC implementing C99 features.

The following code:
printf("%llu\n", ULLONG_MAX); will print UINT_MAX.

Pretty stupid of MS considering that it does recognize the long long format
strings and they have had the __int64 type for years.

This works with VC for instance.
printf("%I64d\n", LLONG_MIN);

All they had to do was to let %lld do the same as %I64d
 
P

Peter Nilsson

Jack Klein said:
Mark Bruno said:
Hey, I'm learning about the limits header, and I don't understand one
snippit of code. If I code:

#include <limits.h>
#include <stdio.h>
int main()
{
printf("Smallest signed long long: %lld\n", LLONG_MIN);
return 0;
}
I get the output:
Smallest signed long long: 0

Why is this? I even check in my limits.h file, where I see:
#define LLONG_MIN 0x8000000000000000 /*minimum signed __int64 value */

Why won't it print the limit?

I don't believe 0x8000000000000000 is a legal definition for [LLONG_MIN]

Why not?

Because, for conformance with C99, such a constant would probably have the
wrong type. Assuming that the given value is too large to actually be a
valid (signed) long long, then it has type unsigned long long according to
6.4.4.1p5, and it would then violate 5.2.4.2.1p1.

As a test, I'd try...

printf("%lld\n", (long long) (LLONG_MIN / 2));
 
C

CBFalconer

pete said:
Because, in C99, with few exceptions, the constants in limits.h,
have to have the same type as the type to which they apply.

What is 0x80.....0? It is an unsigned long long, probably 1
greater than LLONG_MAX. When read as a long long by the printf
code an overflow and undefined behavior results. This is why you
will see such constructs (for 2's complement machines) as:

#define INT_MIN (-INT_MAX - 1)

in limits.h. Great care needs to be taken in the printf (or
equivalent code) to handle these extreme values correctly.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,125
Messages
2,570,748
Members
47,302
Latest member
MitziWragg

Latest Threads

Top