print 64bit-integer

C

chunpulee

hi

os is linux

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
long long ll = 101ll;
long long i = 230ll;

printf("%d %lld\n", i, ll);
printf("%lld %d\n", ll, i);

return 0;
}

output:
230 433791696896
101 230

ll is printed 433791696896, why?
 
S

Spiros Bousbouras

os is linux

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
long long ll = 101ll;
long long i = 230ll;

printf("%d %lld\n", i, ll);

You are telling printf() that the first argument is int when in
reality it is long long. This is undefined behavior meaning that
the behavior of the programme after that becomes unpredictable.
printf("%lld %d\n", ll, i);

This is again undefined behavior for the same reason.
return 0;

}

output:
230 433791696896
101 230

ll is printed 433791696896, why?

Trying to understand why a C programme with undefined behavior
emits a certain output can be as pointless as trying to
understand why a specific sequence of numbers won the lottery.
The general idea is that on your system int occupies fewer bytes
than long long so printf() ends up reading the wrong number of
bytes possibly from the wrong place in memory or from the wrong
registers. If you want any more insights you should instruct
your compiler to translate your code into assembly and study the
output in order to determine what's happening. Note that such an
exercise will not increase in any way your understanding of C.
 
C

Chris McDonald

Richard Heathfield said:
You're printing a long long int using %d, which is for int, not long
long int. C99's 7.19.6.1(9) says in part: "If any argument is not
the correct type for the corresponding conversion specification,
the behavior is undefined."


Given the (unstated) question posed by the OP,
shouldn't they be directed to the header <inttypes.h> header
and the PRId64 modifier for a more helpful, portable solution?
 
C

Chris McDonald

Richard Heathfield said:
I'm not convinced about the "portable"! :) Nor am I convinced of
the existence of a PRId64 modifier, but this may simply be because
I have paid little attention to C99. I have taken a brief look at
what the Standard has to say on the matter, but alas, I remain
unconvinced. Can you convince me that PRId64 (a) exists at all, and
(b) is /required/ to exist?


An *existence* proof is that it exists in gcc 3.2.2 (and probably beyond),
certainly in gcc 4.0.1 on OS-X (you may choose to just believe me on that).

I believe that this makes it widely, though not universally, portable.

No, I can't interpret Sect 7.8.1 to read that it /must/ exist.
 
C

Chris McDonald

Richard Heathfield said:
For maximum portability, however, it should be avoided.


This appears to be a case of reductio ad absurdum,
the crux of much heated debate on c.l.c.

For maximum portability, a C program should not do anything significant.
 
J

James Kuyper

Chris said:
Given the (unstated) question posed by the OP,
shouldn't they be directed to the header <inttypes.h> header
and the PRId64 modifier for a more helpful, portable solution?

PRId64 is for int64_t. Support for int64_t is optional, and even if it
does exist, it's entirely permissible for long long to be a type whose
size might be greater than 64 bits, might have padding, or might not use
2's complement representation; any one of those features would render it
unusable for int64_t.
 
C

Chris McDonald

PRId64 is for int64_t. Support for int64_t is optional, and even if it
does exist, it's entirely permissible for long long to be a type whose
size might be greater than 64 bits, might have padding, or might not use
2's complement representation; any one of those features would render it
unusable for int64_t.


James, I find it a little difficult to follow your argument
(you seem to be arguing against both sides).

The OP asked about 64-bit integers, it's there in the subject line.
I believe that the discussion around long long is a red herring.
 
J

James Kuyper

Chris said:
James, I find it a little difficult to follow your argument
(you seem to be arguing against both sides).

Is there a rule that says there only have to be two sides?

The point I raised is not inconsistent with anything Richard has said,
though his failure to raise the same point suggests that he might not
have thought about it. Alternatively, the comments he has made so far
might have been intended as a roundabout way of raising that same point
- this would not be an unusual way of doing things for him.

However, my response goes directly against your suggestion of using
PRId64. So if I must choose sides, it would seem to me that I have.
The OP asked about 64-bit integers, it's there in the subject line.
I believe that the discussion around long long is a red herring.

Yes, there is one reference to 64-bit integers in the Subject: header,
but none in the message itself, which contains two uses of long long,
and two uses (that should have been four) using %lld. I think it's
pretty clear that the OP conflated 64-bit integers with long long; for
that reason alone, it would be useful to point out the distinction
between the two concepts.

It's not clear, if he were aware of the distinction, which of the two
things his question would really have been about. However, since long
long is referred to more frequently that 64-bit, my guess is that he
would have re-written the subject line to match the body of his message,
and not vice-versa.

More directly to the point, the suggestion of using PRId64 should not
have been made without an accompanying recommendation that he replace
long long with int64_t, or at least do a cast in the printf()
statements. If he is going to use int64_t, the code should also contain
a test of one of the appropriate macros to ensure that it's actually
available. Note that the possible unavailability of PRId64, which
Richard was talking about, is directly related to the possible
unavailability of int64_t.
 
K

Keith Thompson

chunpulee said:
long long ll = 101ll;
long long i = 230ll;
[...]

A style point: The lowercase letter 'l' can be difficult to
distinguish from the digit '1'. Use uppercase 'L' for numeric
suffixes:

long long ll = 101LL;
long long i = 230LL;

Or, at least in this case, don't bother with the suffix:

long long ll = 101;
long long i = 230;

There are cases where you need to make sure that a literal is actually
of type long long, but this isn't one of them. 101 and 230 are valid
values of type int, and they'll be implicitly converted to type long
long by the initializer. This conversion will almost certainly take
place at compile time, not run time, so there's no cost.
 
A

Antoninus Twink

Chris McDonald said:

EXACTLY.

And funnily enough, all the programs Heathfield writes are maximally
portable.
Conclusion: even though the majority of C code is not destined to be
part of a 100% ISO C program, there are still great benefits to be
had in keeping the C code as portable as possible.

For godsake get a grip, Heathfield. PRId64 and friends ARE ISO C. They
are 100% ISO C and have a valid place in any 100$ ISO C program.

Just because you are a fundamentalist who rejects the CURRENT ISO C
STANDARD, that doesn't mean other people aren't interested in how to
write portable code that follows THE CURRENT ISO C STANDARD.
 
A

Antoninus Twink

Actually, in all honesty I was making a much, much more general
point, and one that I've made many times before, and it's to do
with the general (un)availability of C99.

Yeeeeeeawwwwn. You're a real cure for insomnia, Heathfield, when you get
on your favorite hobby horses.

C99 is the CURRENT ISO C STANDARD. Most compilers for most platforms
implement most of it. Perversely refusing to use /any/ C99 features
because not /all/ C99 features are available is the approach of a
fundamentalist.
 
J

jacob navia

Richard said:
James Kuyper said:



How kind. :)

Actually, in all honesty I was making a much, much more general
point, and one that I've made many times before, and it's to do
with the general (un)availability of C99.

Until C99 becomes as widely available as C90 currently is, I stick
to programming in their common subset, and therefore I don't claim
to have a huge amount of C99-specific experience.

This is OFF TOPIC

Your personal preferences as to what times you take out your
dog, or your 9 year old (or was 10) compiler that you use
are off topic here.

Here we discuss the C language as defined by the standard!
I was vaguely
aware of the PRIxN stuff, but a quick search for PRId64 yielded no
hits,

What a lie!

Just type

PRId64

in google and you obtain 1000 hits!
Yes, ONE THOUSAND hits. And then heathfield says

"yielded no hits"
 
K

Keith Thompson

jacob navia said:
This is OFF TOPIC

Wrong. C90 is topical. So is K&R C, pre-K&R C, and even, I would
argue, BCPL.

Unless, of course, somebody you don't like happens to mention it.

[...]
What a lie!

You should stop accusing people of lying. It makes you look like a
malicious idiot.
Just type

PRId64

in google and you obtain 1000 hits!
Yes, ONE THOUSAND hits. And then heathfield says

"yielded no hits"

He searched *the standard* for PRId64 and got no hits. He also
explained why he got no hits, in text that you snipped. (Isn't Google
off-topic anyway?)
 
A

Antoninus Twink

Here we discuss the C language as defined by the standard!

For Richard Heathfield, the CURRENT C STANDARD is obviously offtopic, as
decided by his personal whim.
What a lie!

Just type PRId64 in google and you obtain 1000 hits!

Heathfield is a liar all the way through to the marrow of his bones.

His dishonesty and hypocrisy and arrogance make me feel physically sick.
 
J

jameskuyper

jacob said:
This is OFF TOPIC

The unavailability of C99 is entirely on topic here, as are
appropriate ways to deal with that unfortunate fact. Even claims that
it's not a fact are on-topic here, as you should well no from
extensive discussions you yourself contributed heavily to.
What a lie!

Just type

PRId64

in google and you obtain 1000 hits!
Yes, ONE THOUSAND hits. And then heathfield says

"yielded no hits"

RH didn't say where he searched. What makes you think he searched
using google? For this kind of question, I don't see any reason why he
would search anything other than some version of the C standard. A
google search could easily pick up a thousand hits for a popular but
non-standard extension - why waste time with that, when the question
is about what the standard itself says?

I searched n1256.pdf for PRId64, just like he probably did, and got no
results, just like he did. The difference was that I'm a lot more
familiar with C99 than he is, so I knew that PRId64 was in fact valid.
I furthermore had a vague memory that the relevant parts of the
standard didn't actually use the exact bit sizes, but a variable fill-
in of some kind. Therefore, I searched for PRId, and found PRIDN in
7.8.1p2, just as Richard probably did when he went back the second
time.
 
J

jacob navia

Keith said:
You should stop accusing people of lying. It makes you look like a
malicious idiot.


He searched *the standard* for PRId64 and got no hits.

Obviously he got no hits!

The standard says:

The fprintf macros for signed integers are:
PRIdN PRIdLEASTN PRIdFASTN PRIdMAX PRIdPTR

etc.

No, of course you will not say that he is a malicious
idiot...





He also
 
C

Chris McDonald

It's so very annoying that, while the sun shines in Australia, there
can be intelligent discussion here about C programming, regardless of
how strictly it follows the (many) formal C standards.

However, once the sun sets on Australia and rises in many other countries in
the world, the knives are out and character assassination takes over....
 
K

Keith Thompson

jacob navia said:
Keith Thompson wrote: [...]
He searched *the standard* for PRId64 and got no hits.

"He" being Richard Heathfield.
Obviously he got no hits!

Right, because the word PRId64 does not occur in the standard.
The standard says:

The fprintf macros for signed integers are:
PRIdN PRIdLEASTN PRIdFASTN PRIdMAX PRIdPTR

etc.

Exactly. None of those will show up in a search for PRIdN, unless
your PDF reader has a search function that recognizes N as a match for
64.

He did a quick search for PRId64 and didn't find it.
No, of course you will not say that he is a malicious
idiot...

Of course not; why would I? He made a minor error in not realizing
that the standard refers to PRIdN rather than mentioning PRId64
explicitly. He then acknowledged the error. Here's what he
wrote:

| Until C99 becomes as widely available as C90 currently is, I stick to
| programming in their common subset, and therefore I don't claim to
| have a huge amount of C99-specific experience. I was vaguely aware of
| the PRIxN stuff, but a quick search for PRId64 yielded no hits, hence
| my question to Chris earlier on. (I now realise why I got no hits, of
| course.)

Perhaps you'd care to explain why this prompted you to jump into the
discussion and call him a liar.

Incidentally, I didn't say you were a malicious idiot either. I
merely said that your unfounded accusations make you look like one.
 
S

Spiros Bousbouras

The unavailability of C99 is entirely on topic here, as are
appropriate ways to deal with that unfortunate fact.

I would add to that that the availability of C99 and ways to
take advantage of this fortunate fact are also on topic.

[...]
RH didn't say where he searched. What makes you think he searched
using google? For this kind of question, I don't see any reason why he
would search anything other than some version of the C standard.

Me neither. When the question is about the C standard then one
searches the C standard. I had a recollection that the PRI*
macros exist so I searched the standard for PRI with matching
case and found them easily.

[...]
 
S

Spiros Bousbouras

Until C99 becomes as widely available as C90 currently is, I stick
to programming in their common subset,

How does one print the value of a size_t variable in this
common subset?
 

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
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top