当涉及到变量函数时,为什么参数会被提升,例如浮点被提升为双ext,以及它们的提升顺序是什么?
可变参数-cppreference.com
当调用变量函数时,在左值到右值、数组到指针和函数到指针的转换之后,作为变量参数列表一部分的每个参数都会经历额外的转换,称为默认参数提升:
提升变量函数的参数使处理它们变得更加容易。由于函数代码不知道函数签名中参数的实际类型,因此调用必须通过其他方式传达类型,并且提升在不牺牲灵活性的情况下减少了选项的数量。
例如,考虑变量函数的经典示例-printf。当你给它一个参数时,它已经知道这个参数是双精度的,因为它会被提升。如果没有提升,则必须存在两个不同的修饰符,一个用于单精度,另一个用于双精度。
另一个例子是整体促销。目前,任何类型都可以使用修饰符,虽然短版本的修饰符确实存在,但不需要使用它们,可以简化其代码。
此外,当使用其他一些可变函数时,它提供了更少的惊喜。例如,Posix打开函数被显示为具有2个或3个参数的重载函数,最后一个参数在man中指定为模式t。事实上,C中没有重载,因此没有两个版本的open,只有一个版本,它是可变的。
如果没有促销,则必须确保当使用3参数版本时,最后一个参数恰好是
mode_t
类型,这将非常不方便、违反直觉,并且不这样做可能会导致非常意外的行为。自动促销使我们免于这种情况。
为什么要提升参数
因为这就是语言的指定方式。
你可能会想,为什么语言是这样指定的。我不知道这个选择是否有公开的理由,但我怀疑答案很简单:因为C语言就是这样被指定的
你可能会想,为什么C语言是这样指定的。标准文件N1256讨论了C99标准某些选择的设计原理。它似乎没有涵盖这一选择。此外,C语言早在标准化之前就存在了,C99甚至不是第一个标准版本。在委员会参与之前,这种行为可能已经存在。
值得一提的是,同样的提升规则也适用于调用尚未声明的函数(直到C99),或通过未声明参数的原型调用固定参数函数:
// this is C lanugage
void fun();
int main(int, char [][]) {
float f = 42;
fun(f); // argument promotes to double
undeclared(f); // ill-formed since C99
// argument promotes to double prior to C99
这样做的原因可能类似于在可变参数列表的情况下提升的原因。
问题内容: 我无法理解Xcode在此行面临的问题: 是一个和和是第。Xcode用以下消息突出显示方括号: 下标’subscript(_ :)’要求类型’Substring.Index’和’Int’是等效的 错误消息对我来说没有任何意义。我尝试通过创建带有下标的来获得。这有什么关系?为什么相同的模式在其他地方也起作用? Xcode操场代码重现该问题: 毕竟,我有一个模板字符串和它的两个子字符串。
问题内容: 为什么JavaScript会提升变量? 设计师决定实施吊装时的基本原理是什么?还有其他流行的语言可以做到这一点吗? 请提供文档和/或记录的相关链接。 问题答案: 正如Stoyan Stefanov在“ JavaScript模式”一书中解释的那样,提升是JavaScript解释器实现的结果。 JS代码解释分两次进行。在第一遍中,解释器处理变量和函数声明。 第二遍是实际的代码执行步骤。解释
问题内容: 必须使用无参数构造函数(像Hibernate这样的工具会在此构造函数上使用反射来实例化对象)。 我得到了这个手挥手的答案,但是有人可以进一步解释吗?谢谢 问题答案: hibernate,并且通常通过反射创建对象的代码用于创建类的新实例。此方法需要一个公共的无参数构造函数才能实例化该对象。对于大多数用例,提供无参数构造函数不是问题。 有一些基于序列化的技巧可以解决没有no-arg构造函数
我当时正在研究超载问题,我完全被促销搞糊涂了。我看了SO(函数重载中的隐式转换序列)中的几篇文章,我确信还有一些文章可用,但找不到合适的文章。我也指的是http://www.dcs.bbk.ac.uk/~roger/cpp/week20。htm。我在看Stroustrup的C编程特别版时,看到了下面的解释。 通过在参数表达式的类型和函数的参数(形式参数)之间寻找最佳匹配,可以从一组重载函数中找到要
我看到不同版本的部分。
如果答案是“编译器只是不够聪明”,那么(向后兼容?)为什么不能让它变得更聪明?