Search code examples
cwindowsvisual-c++linkerportable-executable

COMDAT vs BSS definitions


When compiling and linking C code with the Microsoft compiler, definitions with the same name in different object files have several possible outcomes depending on the kind of definition.

int x[5] = {1};
int x[5] = {1};

Two initialized data definitions; this is an error.

int x[5];
int x[10];

Two BSS definitions. The larger one wins, the smaller one is discarded, and the result is as if only the larger definition were present.

int x[5] = {1};
int x[10];

An initialized data definition and a BSS definition. The data definition wins even though it's smaller, and the BSS definition is discarded.

My question is, what if you have a situation like the third case except the initialized data definition is COMDAT? Is the BSS definition still discarded even if larger? Or does it depend on the COMDAT Selection field, e.g. would the BSS definition win only in the case of IMAGE_COMDAT_SELECT_LARGEST and the data definition win in other cases?

(I'm assuming a weak external definition will be overridden by a BSS definition regardless of sizes; please correct me if this is not the case.)


Solution

  • Per experiment with the Microsoft linker, COMDAT initialized definitions still win and corresponding BSS definitions are discarded even if larger. I don't know whether there are any exotic flags that would change this result.