Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C11类型泛型表达式-为什么不添加函数重载?_C_Generics_Overloading_C11 - Fatal编程技术网

C11类型泛型表达式-为什么不添加函数重载?

C11类型泛型表达式-为什么不添加函数重载?,c,generics,overloading,c11,C,Generics,Overloading,C11,我刚刚阅读了维基百科关于2011年12月发布的新版C标准的文章,我看到其中一个新增功能是“键入泛型表达式”: 使用\u generic关键字键入泛型表达式。例如 以下宏cbrt(x)转换为cbrtl(x),cbrt(x)或cbrtf(x) 取决于x的类型: #define cbrt(X) _Generic((X), long double: cbrtl, \ default: cbrt, \

我刚刚阅读了维基百科关于2011年12月发布的新版C标准的文章,我看到其中一个新增功能是“键入泛型表达式”:

使用
\u generic
关键字键入泛型表达式。例如 以下宏cbrt(x)转换为cbrtl(x)cbrt(x)cbrtf(x) 取决于x的类型:

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

这对我来说很可怕——如果他们要改变语言,为什么不只是像C++那样增加函数重载?

< p> C有一个外部符号的命名空间,并且应用ODR(一个定义规则),使得两个代码>外部代码> /Cuth>两个翻译单元中同名的对象必须具有相同的定义。 尽管可以创建一个支持重载的C ABI,但C的主要优势在于其ABI的简单性。在几乎所有的平台上,“ABI”都是C ABI,无论源语言是什么,它在执行中都扮演着一定的角色。如果符号必须包含类型信息,则这将丢失


TGE(由库使用)只是名称混乱的手动操作版本。它确实(或将在可能非常遥远的将来的某个时候)完成它需要做的工作,以允许
typedef
声明控制数学密集型内部循环的生成。需要像C++这样的语言的人应该把它移植到C++。

可能是因为这需要名字的修改,并且在编译时可以完全解决泛型。无论如何,如果你对泛型编程很认真,你就不应该看C。函数重载可能会在几乎所有的实现中引起一个巨大的向后兼容性问题(想想C运行时/链接器/加载程序如何处理符号)@CatPlusPlus:允许对声明为“inline”的函数重载将提供常规函数重载99%的好处,而不会出现名称混乱问题。即使希望能够从其他模块调用重载函数,也可以简单地在头文件中包含重载的“内联”函数,然后这些函数将为不同的参数类型调用不同名称的函数。函数的名称将在头文件中指定,因此不需要特定于编译器的修改。这会有什么问题吗?@supercat:Except
inline
不能保证(也不应该保证)实际的内联(另外,它是一个可以关闭的优化,当优化设置更改时,您不能让代码中断)
\u Generic
是一种避免损坏的方法,通过创建一组已损坏的名称来避免损坏。@CatPlusPlus:编译器确实可以自由生成函数的实际链接实例,而不是内联,但我的理解是,在这种情况下,编译器会将“内联”转换为“静态”,从而将函数声明为“内联”只能从声明它的模块调用。因为这样的函数没有内部链接,编译器可以自由地使用该名称执行任何操作,只要该名称与任何其他模块中的任何内容都不匹配。如果需要,编译器可以简单地分配guid(去掉标点符号)——这真的不重要。