3

I'm writing a program for my study and therefore I have to descripe a few wars to get the limits of some data types. When I'm writing this:

#include <limits.h>
#include <stdio.h>

int main(void)
{
    printf("%d\n", CHAR_BIT);
    printf("%d\n", LONG_BIT);
    return 0;
}

but it gives me the following error:

a.c: In function ‘main’:
a.c:7:17: error: ‘LONG_BIT’ undeclared (first use in this function)
  printf("%d\n", LONG_BIT);
                 ^
a.c:7:17: note: each undeclared identifier is reported only once for each function it appears in

even gcc -E gives me this

int main(void)
{
 printf("%d\n", 8);
 printf("%d\n", LONG_BIT);
 return 0;
}

But a grep in limits.h doesn't give me the answer. But bits/xopen_lim.h has this declaration and it should be included when

__USE_XOPEN

is declared, but even a manual declaration won't give me a result.

So where is the problem? A look in the manpage says there is a LONG_BIT macro but gcc says no.

gcc version 4.8.0 (GCC) OS arch

[edit] For those who say LONG_BIT is not a c-standard, type

man 0 limits.h

and search for LONG_BIT. For me there are two entries under Numerical Limits and therefore I think LONG_BIT exist. And no, including bits/xopen_lim.h is not realy an option, because it should be included by limits.h and not manually

hellow
  • 12,430
  • 7
  • 56
  • 79

3 Answers3

2

LONG_BIT is not a thing in standard C.

For a portable approach, just do this:

CHAR_BIT * sizeof(long)
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • 1
    Downvoted: This is *NOT* portable, that is why LONG_BIT is necessary. See http://stackoverflow.com/questions/3957252. – Loic Aug 08 '16 at 11:15
  • @Loic - This isn't clear. Firstly, it sounds like you're claiming that `LONG_BIT` is *more* portable (even though it's not a standard thing). Secondly, I struggle to understand what part of it is non-portable (in a way that `LONG_BIT` would fix on platforms where it does exist). – Oliver Charlesworth Aug 08 '16 at 11:51
  • 1
    The size of an integer (which you suggested) is **greater than or equal to** its width. How to compute the width is explained in: stackoverflow.com/questions/3957252. With "LONG_BIT is necessary", I meant any macro for the suitable value; LONG_BIT is non-standard, indeed. See also https://gmplib.org/manual/Integer-Import-and-Export.html#Integer-Import-and-Export: "However on Cray vector systems it may be noted that short and int are always stored in 8 bytes (and with sizeof indicating that) but use only 32 or 46 bits.". – Loic Aug 11 '16 at 19:32
  • @loic - That's not possible. log2(x) is never greater than x (where x is the maximum possible value of a type). – Oliver Charlesworth Aug 11 '16 at 22:35
  • @loic: also bear in mind that whether it's greater than the size of the type is irrelevant. sizeof(x) returns a size_t, not the type of x. – Oliver Charlesworth Aug 11 '16 at 22:43
  • 1
    Your last arguments are irrelevant to the question. Your original suggestion is just not portable (but happens to work on common hardware). According to the documentation of gmp: On Cray vector systems, the *size* (in bits) of an int is *64*, but the *width* (in bits) of an int is only *46*. Or, for the sake of using logarithms: size == log2(2^64) > log2(2^46) == width. This definition may help: For the width of a given unsigned type, the maximal value of this type is 2^width-1. See also: https://www.securecoding.cert.org/confluence/display/c/INT35-C.+Use+correct+integer+precisions. – Loic Aug 12 '16 at 15:34
  • @Loic - Yup you're right - I misinterpreted your "greater than or equal to its width" statement as being about overflow (as suggested in the linked question). If the aim is to get the width (and not the size) then I agree this approach isn't going to work on any platform with padding bits. – Oliver Charlesworth Aug 13 '16 at 12:56
2

Your issue is that you shouldn't be defining __USE_XOPEN. If you take a look at /usr/include/features.h you will see it explicitly undefines it and then redefines these macros based on feature test macros. You probably want to define _XOPEN_SOURCE instead, something like:

gcc -D_XOPEN_SOURCE=700 -o longbit longbit.c

From features.h:

_XOPEN_SOURCE Includes POSIX and XPG things. Set to 500 if Single Unix conformance is wanted, to 600 for the sixth revision, to 700 for the seventh revision.
_XOPEN_SOURCE_EXTENDED XPG things and X/Open Unix extensions.

Also, wrt directly including xopen_lim.h:

/*
 * Never include this file directly; use <limits.h> instead.
 */

So, I wouldn't recommend directly including it. Also, see man feature_test_macros or info '(libc)Feature Test Macros'.

Cristian Ciupitu
  • 20,270
  • 7
  • 50
  • 76
FatalError
  • 52,695
  • 14
  • 99
  • 116
0

http://www.cplusplus.com/reference/climits/

There is nothing as such LONG_BIT in limits.h

Aman Singhal
  • 835
  • 1
  • 11
  • 24
  • 1
    I wouldn't use cplusplus.com as a reference for anything. http://cppreference.com is substantially more accurate. But the C standard is the ultimate reference. – Oliver Charlesworth Apr 04 '13 at 17:15
  • 2
    http://pubs.opengroup.org/onlinepubs/7908799/xsh/limits.h.html http://www.unix.com/man-page/opensolaris/3head/limits.h/ – hellow Apr 04 '13 at 17:21