22

I was just reading the Wikipedia article on C11, the new version of the C standard released in Dec 2011, and I saw that one of the added features was "type-generic expressions":

Type-generic expressions using the _Generic keyword. For example, the following macro cbrt(x) translates to cbrtl(x), cbrt(x) or cbrtf(x) depending on the type of x:

#define cbrt(X) _Generic((X), long double: cbrtl, \
                              default: cbrt, \
                              float: cbrtf)(X)

This looks pretty horrible to me - if they are going to change the language anyways, why not just add function overloading like in C++?

Suraj Jain
  • 4,463
  • 28
  • 39
HighCommander4
  • 50,428
  • 24
  • 122
  • 194
  • 14
    Probably because that'd require name mangling, and _Generic can be resolved completely at compile-time. Anyway, if you're serious about generic programming you shouldn't be looking at C. – Cat Plus Plus Jan 07 '12 at 23:33
  • 4
    function overloading would likely incur a huge backwards compatibility problem in virtually all implementations (think how C runtimes/linkers/loaders treat symbols) – nos Jan 07 '12 at 23:36
  • 3
    @CatPlusPlus: Allowing overloading for functions declared "inline" would have provided 99% of the benefit of general function overloading, without any name-mangling issues. Even if one wants to be able to call an overloaded function from other modules, one could simply include within the header file overloaded "inline" functions which would then call differently-named functions for different parameter types. The names of the functions would be specified in the header file, so no compiler-specific mangling would be required. Would there have been any problem with that? – supercat Jan 07 '12 at 23:51
  • 1
    @supercat: Except `inline` does not guarantee (nor should it) actual inlining (plus it's an optimisation that can be turned off, and you can't let code break when optimisation settings change). `_Generic` is a way to avoid mangling, by creating a closed set of already-mangled names. – Cat Plus Plus Jan 07 '12 at 23:59
  • @CatPlusPlus: It's true that a compiler is free to generate an actual linked instance of a function rather than inlining it, but my understanding was that in such cases the compiler converts "inline" to "static", and thus a function declared "inline" is only callable from the module where it is declared. Because such functions do not have internal linkage, compilers would be free to do anything they want with the name provided only that it doesn't match anything in any other module. A compiler could simply assign GUIDs (with punctuation removed) if desired--it really wouldn't matter. – supercat Jan 08 '12 at 00:09
  • @supercat: No, they're usually merged into one, because otherwise it could increase the code size significantly. – Cat Plus Plus Jan 08 '12 at 00:22
  • @CatPlusPlus: Compile-time-generated GUIDs would be less than ideal, since it would be good if matching definitions could be merged. On the other hand, functions which are declared `inline` but aren't inlined are required *not* to have "normal" names. If portions of a project are build with different compilers that mangle the names of inline functions differently but do so in a manner which wouldn't produce collisions (e.g. have each compiler revision prepend its names with a GUID for that compiler version) the worst that could happen if parts of a project were... – supercat Jan 08 '12 at 04:31
  • @CatPlusPlus: ...compiled with different compilers would be that if two modules containing the same inline function are compiled with different compilers, the function could get needlessly duplicated. Mangling names to allow for function overloading, though, wouldn't make the problem any worse than it would be otherwise. A project could perfectly legitimately have multiple different inline functions with the same name; if a compiler doesn't use name mangling I don't see how a linker could possibly keep them straight. – supercat Jan 08 '12 at 04:34
  • Note that the `` would allow you to avoid writing an `_Generic` expression for `cbrt()` specifically, and most of the other mathematical functions from `` and `` — `modf()` is an explicit exception. – Jonathan Leffler Feb 13 '17 at 05:20

1 Answers1

28

C has one namespace for external symbols, and applies the ODR (One Definition Rule) such that two extern objects with the same name in two translation units must have the same definition.

Although it's possible to create a C ABI that supports overloading, the main strength of C is its ABI simplicity. On almost all platforms "the" ABI is the C ABI, and it plays some role in execution no matter the source language. This would be lost if symbols had to include type information.

TGE (as used by the library) is just a manually-operated version of name mangling. It does (or will do, sometime in the possibly very distant future) the job it needs to do, to allow typedef declarations to control generation of math-intensive inner loops. People who need the features of a language like C++ should port to C++.

kiwidrew
  • 3,063
  • 1
  • 16
  • 23
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421