Subject: lib/34516: size_t should be equivalent to unsigned long
To: None <lib-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Christian Biere <christianbiere@gmx.de>
List: netbsd-bugs
Date: 09/13/2006 06:30:00
>Number:         34516
>Category:       lib
>Synopsis:       size_t should be equivalent to unsigned long
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    lib-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Sep 13 06:30:00 +0000 2006
>Originator:     Christian Biere
>Release:        NetBSD 3.99.23
>Environment:
System: NetBSD cyclonus 3.99.23 NetBSD 3.99.23 (STARSCREAM) #3: Thu Jul 27 02:06:27 CEST 2006 bin@cyclonus:/o/NetBSD/obj/sys/arch/i386/compile/STARSCREAM i386
Architecture: i386
Machine: i386
>Description:
At least on i386, size_t is an alias for unsigned int. In practice,
unsigned long and size_t are essentially the same types on all
platforms I know of despite being treated as different types by
C compilers if defined as such.

In my opinion and experience actually, using unsigned long would be
less error-prone because it doesn't hide typically bugs like passing a
pointer an int where a pointer to a size_t is expected, or passing an
int to a printf() function with a format specifier %d or %u. This is
certainly GCC-specific, nonetheless currently such bugs are not
obvious when compiling on i386. They only become apparent when
compiling on a 64-bit platform where int and long have different bit
widths.

Also, it is, unfortunately, still extremely common to use "int"
instead of "size_t". As long this situation persists, it always takes
a "pedant" or someone with a 64-bit machine before such very simple
but often dangerous bugs are fixed.

I suggest this change for all 32-bit platforms, of course.

>How-To-Repeat:

Consider the following - completely bogus - program.

1. cc -W -Wall -Wformat=2 blah.c
   No warnings on i386.

2. cc -W -Wall -Wformat=2 -Dsize_t='unsigned long' blah.c
   Useful warnings even on i386 where long and int are technically
   identical.

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

void
blah(size_t *ptr)
{
  *ptr = 1;
}

int 
main (void)
{
  int y;
  size_t x = 1;

  blah(&y);		/* No warning despite bug */
  printf("%d", x);	/* No warning despite bug */
  return 0;
}

>Fix: