如何解决函数调用 n1256 6.5.2.2 p5, p6
我正在阅读 N1256 6.5.2.2 函数调用。有些部分对我来说很难理解。我用粗体句子或一些关键字在谷歌上搜索,但找不到我的问题的直接答案。所以我问我的。
在 6.5.2.2 p5(强调我的)
如果表示被调用函数的表达式有一个指向函数的类型指针,返回一个 对象类型,函数调用表达式与该对象类型具有相同的类型,并具有 按 6.8.6.4 规定确定的值。否则,函数调用的类型为 void。 如果 尝试修改函数调用的结果或在下一次之后访问它 序列点,行为未定义。
第一季度。加粗的句子是什么意思?有没有办法修改一个函数调用的结果或者在下一个序列点之后访问它?
6.5.2.2 p6 的一部分(强调我的)
如果表示被调用函数的表达式的类型不包括 原型,对每个参数执行整数提升,以及 有类型 float 被提升为 double。这些被称为默认参数 促销活动。如果参数的数量不等于参数的数量,则 行为未定义。 如果函数定义的类型包含原型,并且 原型以省略号 (,...) 或 后面的参数类型结束 促销与参数类型不兼容,行为未定义。 如果函数是用不包含原型的类型定义的,并且 升级后的参数与升级后的参数不兼容 促销,行为未定义,以下情况除外: ...
在 6.7 p4,用于定义兼容类型。
同一作用域内所有引用同一对象或函数的声明应指定 兼容类型。
形参不是对象,只是一个占位符。 Q2。函数调用的参数和参数可以是同一个对象吗? Q3。为什么标准将提升的参数与参数进行比较?如果有要比较的参数,则不会进行提升,因为只有在编译器不知道被调用者期望的数据类型时才会进行默认参数提升。
解决方法
(替换之前的答案)
对于 Q3,这似乎是关于表示被调用函数的表达式不包含原型但函数定义包含原型的情况。在这种情况下,论点将受到提升。
void foo1(short s) { // defined with a prototype
// ...
}
void foo2(int i) { // defined with a prototype
// ...
}
void bar(void) {
void (*ptr)(); // no prototype
char c = 'x';
short s = 8;
int i = 1234;
long l = 12345678;
ptr = foo1;
ptr(c); // UB; char promoted to int which is not compatible with short
ptr(s); // Also UB! short promoted to int which is not compatible with short
ptr(i); // likewise UB
// AFAICT there is no way to call foo1 through ptr without UB
ptr = foo2;
ptr(c); // OK; char promoted to int which is compatible with int
ptr(s); // likewise OK
ptr(i); // likewise OK
ptr(l); // UB; long is not compatible with int.
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。