|
View:
New views
3 Messages
—
Rating Filter:
Alert me
|
|
|
Distinguishing between long and long long on an LP64 machine?Suppose that I have a signed integer type coming from a header
file, and that I already know that this integer type is a 64-bit type. (Think off_t, for example.) If I'm using gcc on a machine where both long and long long also have 64 bits, is there any simple C99 (+ gcc extension) code that will allow me to figure out whether this type is ultimately defined as long or long long? The original motivation was to avoid gcc -Wall warnings when doing: off_t my_offset; ... printf("%lld", my_offset); If off_t is defined as long rather than long long then this will give a warning, even though the sizes match. (So of course, this actually gives a programmatic way to distinguish: have a configure script do a test compilation with -Wall -Werror. But I'm looking for a simple C expression or function that could detect the difference.) It seems that some LP64 platforms (e.g., OS X 10.6) define off_t to be long long, while others (e.g., Linux/x86_64, or at least the three different flavours of Linux that I tested) define off_t to be long. Of course, the solution to avoiding printf warnings is as easy as adding a cast: printf("%lld", (long long)my_offset); so in this particular motivating case there isn't really any problem. But I'm still curious to know whether there's a simple way for a gcc *user* to distinguish between long and long long when both are 64 bits. typeof doesn't seem to help here. I guess I'm really after some imaginary extension 'rank_of' that lets me do if (rank_of(off_t) == rank_of(long long)) < code using %lld > else < code using %ld > ... Mark |
|
|
Re: Distinguishing between long and long long on an LP64 machine?Hi Mark,
> If I'm using gcc on a machine where both long and long long also have 64 bits, > is there any simple C99 (+ gcc extension) code that will allow me to figure > out whether this type is ultimately defined as long or long long? If you are using C++, yes. If you are using C... I don't think so. For your example, this is how I do it: off_t my_offset; //... printf("%lld", (long long)my_offset); Why? Because there is no printf format specifier for off_t: printf("%{off_t}d", my_offset); And *that* is really the problem you are running into. (If I recall correctly, C/C++ Users Journal had published an article on extensible printf called eprintf, and there you could register off_t handling.) If you are using C99, then you could do it this way: #include <inttypes.h> //... off_t my_offset; //... printf("%"PRId64, (int64_t)my_offset); That's even more port-robust. For the ultimate in future-protection paranoia, you could add a static check to ensure that sizeof(off_t) == sizeof(int64_t). I think that's about as close as you can get, and it doesn't distinguish between long int and long long if both are 64-bit. > ... I'm still curious to know whether there's a simple way for a gcc *user* to > distinguish between long and long long when both are 64 bits. typeof doesn't > seem to help here. I guess I'm really after some imaginary extension > 'rank_of' that lets me do C? I don't think so. C++? Yes, standard C++. (You can use C++ as a "better C". But these days, that will probably get you scowls from C folks who eschew C++.) Sincerely, --Eljay |
|
|
Re: Distinguishing between long and long long on an LP64 machine?On Tue, Oct 27, 2009 at 12:32 PM, John (Eljay) Love-Jensen
<eljay@...> wrote: > Hi Mark, > >> If I'm using gcc on a machine where both long and long long also have 64 bits, >> is there any simple C99 (+ gcc extension) code that will allow me to figure >> out whether this type is ultimately defined as long or long long? > > If you are using C++, yes. If you are using C... I don't think so. Many thanks for the response, and sorry for the delay in replying. > For your example, this is how I do it: > > off_t my_offset; > //... > printf("%lld", (long long)my_offset); Thanks. That's more-or-less what I've ended up with, modulo worrying about Windows/MSVC, and about platforms that don't have long long. I just wanted to make sure I wasn't missing some other obvious solution for silencing these gcc warnings. To provide a bit of context, I was working on a portion of the Python codebase, which mostly tries to be C89 conforming. C99 features like long long or int64_t are used, but they're usually enclosed in appropriate preprocessor conditionals, with some C89 fallback code that's supposed to work everywhere. (And catering to MSVC adds another layer of complexity.) The code in question (see the _buffered_raw_tell function in [1] if you want the gory details) was printing expressions of type off_t using "%zd", leading (naturally) to gcc warnings on Unix. To a younger and more foolish me it looked like a five minute task to fix this. Now I'm older and wiser! >> ... I'm still curious to know whether there's a simple way for a gcc *user* to >> distinguish between long and long long when both are 64 bits. typeof doesn't >> seem to help here. I guess I'm really after some imaginary extension >> 'rank_of' that lets me do > > C? I don't think so. Okay, thanks. As far as I can tell from staring at the standards, in the absence of permitted oddities like paddings bit or trap representations, it seems that two two's complement signed integer types of different ranks but the same precision are completely indistinguishable (with respect to semantics) within standard C. With gcc, the warning I get from printf seems to be the only visible difference. Mark [1] http://svn.python.org/view/python/trunk/Modules/_io/bufferedio.c?view=markup |
| Free embeddable forum powered by Nabble | Forum Help |