Why you should not use C99 exact-width integer types

Is there really ever a time where you need an integer type containing exactly N-bits? There are C99 types which guarantee at least N-bits. There are even C90 types which guarantee at least 8, 16 and 32 bits (the standard C integer types). Why not use one of those?

I never use C99 exact-width types in code… ever. Chances are that you shouldn’t either because:

Exact width integer types reduce portability

This is because:

1) Exact width integer types do not exist before C99

Sure you could create an abstraction that detects if the standard is less than C99 and introduce the types, but then you would be overriding the POSIX namespace by defining your own integer types suffixed with “_t”. POSIX.1-2008 – The System Interfaces: 2.2.2 The Name Space

GCC also will not like you:

The names of all library types, macros, variables and functions that come from the ISO C standard are reserved unconditionally; your program may not redefine these names.
GNU libc manual: 1.3.3 Reserved Names

From my own experience using GCC on OS X, the fixed width types are defined even when using --std=c90, meaning you’ll just get errors if you try to redefine them. Bummer.

2) Exact width integer types are not guaranteed to exist at all:

These types are optional. However, if an implementation provides integer types with widths of 8, 16, 32 or 64 bits, it shall define the corresponding typedef names.
ISO/IEC 9899:1999 – Exact-width integer types

Even in C99, the (u)intN_t type does not need to exist unless there is a native integer type of that width. You may argue and say that there are not many platforms which do not have these types – there are: DSPs. If you start using these types, you limit the platforms on which your software can run – and are also probably developing bad habits.

Using exact width integer types could have a negative performance impact

If you need at least N-bits and it does not matter if there are more, why restrict yourself to a type which which could require additional overhead? If you are writing C99 code, use one of the (u)int_fastN_t types. Maybe, you could even use a standard C integer type!

The endianness of exact width integer types is unspecified

I am not not implying that the endianness is specified for other C types. I am just trying to make a point: you cannot even use these types for portable serialisation/de-serialisation without feral-octet-swapping-macro-garbage as the underlying layout of the type is system dependent.

If you are interested in the conditions for when memcpy can be used to copy memory into a particular type, maybe you should check out the abstraction which is part of my digest program. It contains a heap of checks to ensure that memcpy is only used on systems when it is known that it will do the right thing. It tries to deal with potential padding, non 8-bit chars and endianness in a clean way that isn’t broken.

This article deliberately did not discuss the signed variants of these types…

Eaton 5115 powering Ubuntu Server 11.10 with NUT

A couple of months ago, I bought a UPS for my server at home. I’m running more remote services on it and figure that anything I can add to protect it is worth while. I bought an Eaton 5115 500 Watt tower model. Only the “Powerware” branded model is listed on the NUT support page but I was banking on the newer model being compatible. For those out there wondering: yes it is.

  1. Install NUT and then configure as per the instructions given here here. For the Eaton 5115 connected via USB, bcmxcp_usb is the correct driver. On Ubuntu this was just a matter of apt-get’ing the “nut” package and modifying ups.conf, upsd.conf, upsd.users, upsmon.conf and nut.conf as specified on the previously linked documentation page.
  2. Disconnect and reconnect the USB connection from the server to the UPS (I had to do this to get everything working).
  3. Test that everything worked by running:

    $ upsc { ups name }

    Where { ups name } is the name chosen for the UPS in ups.conf.

As for the UPS itself: it seems pretty good. I was concerned when I first plugged it in as the fan whirred quite loudly at full speed for a few minutes – but then it slowed down to a very quiet speed. The voltage regulation feature has kicked in a few times (my line is supposed to be a nominal 240 Volts but more often floats around 250 Volts) which I thought was pretty neat.

I haven’t got figures on battery length… might edit this when I do.

Thank you DrayTek

Our home is a wireless nightmare. We have several simultaneous dual-band routers which we used to spread the wifi throughout the house. All of these are running dd-wrt because their stock firmware cannot do what I want them to do. We have:

  • A Cisco E4200 which is the main internet router and is positioned in the middle of the house. It provides two separate wireless networks.
  • A Cisco E3000 which is bridged to the N network. This provides another G network and also acts as our print server (printer is connected to a USB port on the device).
  • A Netgear WNDR3700 which is bridged to the N network and provides yet another G network. Our TV is also connected to this box so it can talk to our media server.

All of these devices are fantastic. I have never needed to reset any of them (yes, never). They just work all the time. However, the above description of my wireless setup is not the point of this post. While I have had a good experience with the reliability of my “routers”, my experience with modem/router combo devices tends to have been less positive: they have never been particularly reliable when placed under load. Using a router, however, means that a separate modem is required to connect to the internet.

Over the last few years, I have had a bunch of different modems and almost all of them have been complete rubbish. Here are the last four which I have had:

  • A Netgear DGND3300. This is actually a modem/router, but it can be placed into a modem only mode via a hidden page (http://(ROUTER_IP_ADDRESS)/setup.cgi?next_file=mode.htm). I used the device initially in the normal modem/router mode until one of its wireless devices started to fail. At which point, I bought the WNDR3700 and continued to use this device as a modem. It lasted probably a year and then it started to crash (the modem had to be power cycled on a more-than-daily basis) but I have a feeling this was triggered by a surge. I give this device a 3/10 – I don’t blame Netgear for the modem component of the device failing, but I do blame them for the wireless giving up so quickly.
  • A Netgear DM111P. This thing was a complete pile of rubbish. From the day it was bought, it needed to be power cycled at least daily. I give this device a 0/10 – it was almost totally useless. This is also why I started to buy Cisco gear.
  • A Cisco X2000. Again, this is another modem/router which can be placed into bridge mode (much more easily than the DGND3700). I thought it was going to be great when it held the connection for 3 days… then it crashed. We kept the device for a few months and it would last anywhere up to 7 days before crashing. I give it a 1/10. It gets one point just to make it clear that it was “better” than the DM111P.
  • A DrayTek Vigor 120. This is the latest modem I have bought. I’ve had it for a couple of weeks now and it has been rock solid. I get good speeds and it holds the ADSL connection excellently.

Unstable modems suck – especially if you are running remote services from a home server. If you go away from home and the modem dies – you’re stuck being unable to log in until you can manually reset the modem. So yeah, thanks DrayTek for making my wireless setup something I don’t need to think about anymore.