3

Possible Duplicate:
How should I print types like off_t and size_t?

I'm using fstat(stream, &fs) to get a file size in C which returns type off_t.

Printing this just gives a warning:

format ‘%d’ expects type ‘int’, but argument has type ‘off_t’

Any ideas how to print this without compiler errors?

Community
  • 1
  • 1
Marcus
  • 7,753
  • 10
  • 40
  • 65
  • Maybe the question http://stackoverflow.com/questions/1401526/use-printf-to-display-off-t-nlink-t-size-t-and-others helps – Lars Noschinski Mar 09 '11 at 20:22
  • @Matteo Italia no, although thats in the title, theres nothing in the answers that confirm how to print off_t – Marcus Mar 09 '11 at 20:32
  • This is a merge candidate, since the answers over on the duplicate aren't really clear and complete. Although at time of writing, I don't think the answers below are entirely correct either. – Steve Jessop Mar 09 '11 at 20:37
  • @Steve Jessop: the problem is that to a large extent, there *is* no really good answer. Until the last C89 compiler is dead and gone, there won't be either. – Jerry Coffin Mar 09 '11 at 20:40
  • @Jerry: True if C89 is required, but IMO answers for C89 are separate from answers for unqualified C, which to me means "C less than 10 years out of date". `off_t` is POSIX-y anyway, and C89+POSIX is an even rarer combination than C89 alone, since it rules out the obvious. I'd call an answer that says, "here's how to do it in C99 - it is impossible to do it portably in C89" clear and complete, if that indeed is the truth about C89. For added bonus it could say how to do it on Windows too. – Steve Jessop Mar 09 '11 at 20:47
  • @Igor K: there's the suggestion to cast, which is the only viable C(89?) alternative. – Matteo Italia Mar 09 '11 at 20:49
  • @Matteo: but cast to what, is the problem. I think in C89 there is no integer type that has a format code and is guaranteed to be at least as big as the POSIX `off_t`. – Steve Jessop Mar 09 '11 at 20:51
  • @Steve Jessop: as much as I *wish* you were right, you're really not. Especially for embedded systems, C89 remains quite common. I'm not sure what you think is ruled out -- I'd have thought the obvious pre-C99 compiler was MS, but they define `off_t` too. – Jerry Coffin Mar 09 '11 at 20:59
  • @Jerry: I did mean MS, I didn't know/remember that they use `off_t`. I claim that it doesn't matter how common C89 is, it still isn't the current version of C, and if you want C89 answers, you have to ask C89 questions. I could probably dig out a K&R C compiler from somewhere, but the fact I can do that doesn't mean every question about C needs to be answered for that compiler. Do answerers on the Java tag have to put up with people saying, "ah, but your answer doesn't work on Java ME", when the question didn't mention mobile? ;-) – Steve Jessop Mar 09 '11 at 21:05
  • @Steve Jessop: You can take things as you wish -- but it takes very little looking to realize that most use of "C" without qualifications refers to C89. Assuming otherwise in an answer (for example) simply provides an answer that's likely to be useless and confusing. – Jerry Coffin Mar 09 '11 at 21:17
  • @Jerry: I dispute "most", but I'll start putting `//` comments in my C answers, and see how often I get back complaints that they don't compile ;-p. I genuinely don't think that C99 is this bewildering mystery that most C programmers cannot comprehend sufficiently to even recognise that if an answer doesn't work on their embedded system, maybe that's why. The exception I suppose would be CS students, who might be handed MSVC and told to get on with it. Which is daft, since MS supports C at all only grudgingly and only for legacy reasons, but hey. – Steve Jessop Mar 09 '11 at 21:23
  • Looking at it another way - would I be doing good or bad if I started in future downvoting any answer that relies on C99 features, where the question doesn't explicitly mention C99? I think bad, because I don't think it's reasonable to say that those answers are useless. All it takes is for users to have a vague idea what standard their compiler supports (if any), and to ask for C89 solutions if they get a C99 answer that their compiler doesn't like. – Steve Jessop Mar 09 '11 at 21:29
  • Anyway, I've added my best effort at C89 to my answer over on that other question. – Steve Jessop Mar 09 '11 at 21:38
  • @Steve Jessop: `//` comments mean little -- Microsoft (for one obvious example) supported them in C before C99 existed. As far as downvoting unless C99 is noted explicitly: no, of course not. Just for obvious example, if they mention using gcc and your answer uses a C99 feature that gcc implements, great. OTOH, if the answer used a non-standard feature of gcc it probably wouldn't merit a downvote either. – Jerry Coffin Mar 09 '11 at 21:56
  • @Jerry: OK, modify my policy a bit to say that mentioning gcc counts as mentioning C99, since we know that gcc more-or-less implements C99. If the real issue is that answers to "vanilla C" questions should work *on Microsoft* then by all means say so. I'll disagree, though, because I don't know off-hand what C99 features MSVC does and doesn't support, so I'd find it very hard to answer that way. For another example, are VLAs "like `//`", in that it's OK to use them in answers to "vanilla C" questions, or "like `intmax_t` and `PRIdMAX`" in that they're useless and confusing? – Steve Jessop Mar 09 '11 at 22:01
  • (Actually I'd say they're useless and confusing even in C99, but for the reason that they're almost impossible to find uses for that are correct and where a fixed-sized array wouldn't work, not because I think they'll bewilder embedded programmers. I'm *asking* about the latter...). – Steve Jessop Mar 09 '11 at 22:02
  • I'm not sure what "latter" you're referring to there, but I'm not sure it matters a lot either. I'm not sure MSVC matters a lot, but it's a reasonable proxy for the hundreds (!) of least-common denominator C compilers -- which, for better or worse, are common in the market that probably represents at least 80% of the real reason to use C any more (i.e., embedded systems that won't support much more than that). I'm not sure why you keep using "bewilder" -- the answers likely to be useless, not bewildering. – Jerry Coffin Mar 09 '11 at 22:39
  • C89-friendly solution: `if (x>ULONG_MAX) printf("%lu%.9lu", (unsigned long)(x/1000000000), (unsigned long)(x%1000000000)); else printf("%lu", (unsigned long)x);` – R.. GitHub STOP HELPING ICE Mar 09 '11 at 23:09
  • @R..: nice, although `off_t` is signed, so add some extra faff for that. – Steve Jessop Mar 10 '11 at 17:11
  • Yeah, `off_t` is signed, and you can *use* negative values for seeking relative to the current position or end-of-file. But you won't ever get them as results (of `lseek` or `ftello`), so it's probably not useful being able to print them. – R.. GitHub STOP HELPING ICE Mar 10 '11 at 19:12

2 Answers2

5

Offset types are usually long integers. Cast it, and print it accordingly.

The actual type below off_t is defined in sys/types.h. You can look it up!

slezica
  • 63,258
  • 20
  • 91
  • 152
  • 1
    Keep in mind that this is not portable; off_t might be of different type on different systems! – Lars Noschinski Mar 09 '11 at 20:25
  • 2
    POSIX defines that `off_t` is signed (http://pubs.opengroup.org/onlinepubs/007908799/xsh/systypes.h.html), although casting it to a sufficiently large unsigned type won't do any harm provided whoever reads the output has their wits about them. – Steve Jessop Mar 09 '11 at 20:29
  • Meant to say "long", not unsigned. Fixed! Thanks. – slezica Mar 09 '11 at 20:31
  • will accept this in a few minutes :) – Marcus Mar 09 '11 at 20:32
  • And on 32 bit systems that support big files, it may well be `long long` rather than just `long`. As you say, for a non-portable solution you can just check `sys/types.h` and use the correct format for whatever it actually is on your implementation. – Steve Jessop Mar 09 '11 at 20:32
0

Found the answer, use:

%lld

Works without any casting.

Marcus
  • 7,753
  • 10
  • 40
  • 65