views:

64

answers:

2

When we are writing a new version of a library we made (in C), we are prohibited from changing, say, the size of a struct to be smaller. Why?

Specifically,

version 1 has this:

struct foo {
    int a;
    int b;
}

version 2 has this:

struct foo {
    char a;
    char b;
}

and we seperate struct definition from declaration, so as to make library user cannot access members of that struct.

+2  A: 

The basic reason is (and i'm not a C programmer here, but i'm fairly confident of my answer) that it would be a breaking change.

Breaking change means that it would be a change that requires library consumers to modify their code, which is never a good thing. That means that they would in turn have to ship a new version of their programs if they wanted to use your library's latest version, which may not always be feasible.

RCIX
I want an example of that user domain change. If the object of that struct is fully maintained by library (malloc/free) and user cannot access the members of that struct, why is this dangerous?
solotim
In that case, it's simply a rule of whoever you're writing code for and you'd have to talk to them. The big reason i can see for them not allowing it is it means more work which could be spent on new features or other more urgent refactoring tasks, and possibly new bugs being introduced into the library.
RCIX
@solotim: Then it is not dangerous, and is perfectly allowed. Only elements the library interfaces with the world should remain reasonably backwards-compliant (unchanged if possible). You are free to mess with the deep internals as much as you want. Note though, "interfaces with the world" is a wide expression - including the functions, but also including the hardware it may be using or memory-mapped areas the structure overlays and so on.
SF.
@RCIX: Thank you anyway.@SF: thanks, your response make me feel confident.
solotim
@SF: Ah, yes you have a good point. I was under the mistaken impression that he had to follow a rule to that effect.
RCIX
+3  A: 

its difficult to guess because there could a number of more or less valid reasons probably all have to do with trying to be backwards compatible and to avoid updating all programs when doing an update.

structs can be (ab)used in many ways, for instance people can have pointers to inside a struct and instead of accessing the struct members through name may wander around using a pointer:

struct {
  int a;
  int b;
  int c;
} s;

and if somebody accesses the struct with

struct s mys;
... 
int *p = &mys.a; ++p; ++p; *p = 3;

it will break if the struct has become smaller

As an example Windows (known for its long history of backwards compatibility headaches) has often the size of the struct as first member in the struct, then apps would read that value first to guess what struct version they were working with, this of course meant there would be a number of similarly named structs corresponding to various versions depending on size (shivers).

of course its not by far enough to keep backwards compatibility but it helps.

Anders K.
@Anders: useful help. Thank you. I thought gtk goes the same way for pseudo "class" discrimination.
solotim