2

In C:
My string length function is returning a size_t value?

Why is it not returning a integer which is conventional? And one more thing I noticed was that when I was trying concatenate this string with another string I received a bus error when I ran the program.

Context: I was kind of playing with gmp library and converting big numbers to strings and I end up with the above situation.

What kind of a string is that? Is my operating system playing a role in this issue? I use a MAC, 64-bit OS.

Edited: The error message I received was:

: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘size_t’

Thanks!

@all: Thanks for the answers but I thought I will put the bus error as another question because it seems to be a different issue.

J...S
  • 5,079
  • 1
  • 20
  • 35
Maverickgugu
  • 767
  • 4
  • 13
  • 26
  • `size_t` _is_ an integer data type. the bus error most likely has absolutely nothing to do with that, you're probably simply overruning a buffer, have a dangling/null pointer somewhere or something to that effect. – Mat Apr 19 '11 at 13:07
  • @Mat the integer part is clarified now, but bus error is becoming common for any program i use strcat for two character pointers. – Maverickgugu Apr 19 '11 at 13:24
  • open a new question for that specifically, with some code snippets that show how you use `strcat`. – Mat Apr 19 '11 at 13:26

6 Answers6

6

The problem is int might be not wide enough to store the whole range of possible length values. For example on 64-bit you can have a string longer than 4 gigabytes and if int is 32 bit you can't possibly return length of such a long string via an int variable.

sharptooth
  • 167,383
  • 100
  • 513
  • 979
3

POSIX strlen() does return size_t.

As to what's caused the bus error, it's impossible to say without seeing the code and knowing more details about the exact nature of your changes. One possibility is that you've caused a buffer overrun or did something with a NULL pointer you shouldn't have done.

J...S
  • 5,079
  • 1
  • 20
  • 35
NPE
  • 486,780
  • 108
  • 951
  • 1,012
3

strlen() always returned size_t ... and the POSIX standard also says that.

I guess the reason is that int has sign and the capacity of even an unsigned int might not be enough for holding size of an element (say if you have a 32bit int on x86-64 with 16GB RAM) ... the example is extreme, but possible.

J...S
  • 5,079
  • 1
  • 20
  • 35
BiGYaN
  • 6,974
  • 5
  • 30
  • 43
2

strlen() returns a size_t since at least ISO C90 -- I just checked in my copy. And this standard should have no technical difference with ANSI C89.

There was a change of convention (size_t wasn't in K&R C), but it was a long time ago.

J...S
  • 5,079
  • 1
  • 20
  • 35
AProgrammer
  • 51,233
  • 8
  • 91
  • 143
  • Thanks! I just realized it now.. Is it advisable to give ISO-C90 a full reading. or use it as a reference as issues comes up! – Maverickgugu Apr 19 '11 at 13:37
2

To address your warning (which is actually an error - you've invoked undefined behavior by passing the wrong type to printf) you should use %zu rather than %d for printing size_t values.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • Yes.. I realized that size_t can be printed using %ld.. But %zu also seems to be good option. Thanks! – Maverickgugu Apr 19 '11 at 13:35
  • 3
    `%ld` is not necessarily correct. In fact it will give warnings on most 32-bit systems where `size_t` is defined as `unsigned int` - even though the type sizes are they same here, `unsigned int` and `unsigned long` are still not *the same type*. – R.. GitHub STOP HELPING ICE Apr 19 '11 at 13:39
1

There is a very simple and logical reason for all of the functions from the standard library to work with size_t when it comes to lengths of memory blocks - the built-in sizeof operator yields a size_t result as well.

Moreover, size_t is unsigned, of a particular size, tied to the architecture and is semantically different than just a generic int which is meant for storing any number from the count of trees around your office to your SO reputation.

Blagovest Buyukliev
  • 42,498
  • 14
  • 94
  • 130