从 C 中的函数返回 0?

Posted

技术标签:

【中文标题】从 C 中的函数返回 0?【英文标题】:return 0 from a function in C?从 C 中的函数返回 0? 【发布时间】:2015-03-09 08:04:00 【问题描述】:

编译为“C”与编译为“C++”之间存在以下差异

struct A 
  int x;
  int y;
;

struct A get() 
  return 0;      

当编译为“C++”时一切正常。 但是,当编译为“C”时;我得到了:

错误:预期的表达式

我可以通过这样做来解决:

return (struct A)0;      

但是,我想知道差异来自哪里。语言中的任何一点都可以参考这种差异的来源吗?

【问题讨论】:

我认为 c++ 编译器会自动将返回值转换为struct A。在 c=+ 中,您不需要 struct A get() 只需 A get() 您是否在 C++ 11 之前使用 C++ 编译器之前尝试过? Pretty sure it pukes there too. 不知何故,我认为这与c++11中引入的自动返回类型推导直接相关。 我认为 this link 可能会有所帮助。给定链接的段落后半部分(以“标量类型的复合文字”开头)回答了您的问题。 你不知道C和C++是两种独立的语言吗?您不妨尝试将其编译为 php,然后询问是什么机制导致执行失败。完全是愚蠢的! 【参考方案1】:

两者使用完全不同的机制,一种是C++11特有的,另一种是C99特有的。

第一位,

struct A get() 
  return 0;

取决于 C++11 中的 [stmt.return] (6.6.3 (2)),它说

(...) 带有 braced-init-list 的 return 语句通过从指定的初始化列表中的复制列表初始化来初始化要从函数返回的对象或引用。 [ 例子:

std::pair<std::string,int> f(const char *p, int x) 
  return p,x;

-- 结束示例 ]

这段话在C(C++11之前的C++也不存在)中不存在,所以C编译器无法处理。

另一方面,

struct A get() 
  return (struct A)0;

使用 C99 中不存在的称为“复合文字”的特性(尽管一些 C++ 编译器,特别是 gcc,将其作为语言扩展提供;gcc 使用 -pedantic 警告它)。语义在 C99 标准的第 6.5.2.5 节中有详细描述;报价是

4 由带括号的类型名称后跟用大括号括起来的初始值设定项列表组成的后缀表达式是复合文字。它提供了一个未命名的对象,其值由初始化列表给出。 (脚注 80)

80) 请注意,这与强制转换表达式不同。例如,强制转换指定转换为标量类型或仅void,并且强制转换表达式的结果不是左值。

所以在这种情况下(struct A)0 是一个未命名的对象,它被复制到返回值中并返回。 (请注意,现代编译器会忽略此副本,因此您不必担心它的运行时开销)

你有它,章节和诗句。为什么这些功能以它们各自的语言存在的方式可能被证明是一个引人入胜的讨论,但我担心,除了各自的标准化委员会之外,任何人都很难对这个问题给出权威的答案。这两个特性都是在 C 和 C++ 拆分方式之后引入的,并且它们不是并排开发的(这样做也没有任何意义)。即使在小事上,分歧也是不可避免的。

【讨论】:

顺便说一句,(struct A)0 究竟返回了什么? AFAIK,return 语句应该是 (struct A)0, 0 @hackks:大括号初始化列表中未提及的内容是零初始化的(参见 C99 中的 6.7.8 (21))。这也发生在正常的结构和数组初始化中。 @Wintermute;如果return 语句为(struct A).x = 0,就会出现这种情况。该参考与数组初始化有关。我问这个是因为我不确定结构,或者可能是这一点从我的记忆中消失了。 好的。在这里找到它:C99-6.7.8: (p17): 每个用大括号括起来的初始化器列表都有一个关联的当前对象。当没有指定时,当前对象的子对象根据当前对象的类型按顺序初始化:数组元素按递增下标顺序,结构成员按声明顺序,联合的第一个命名成员

以上是关于从 C 中的函数返回 0?的主要内容,如果未能解决你的问题,请参考以下文章

从c ++ / c中的函数返回的问题

c语言中的RETURN()返回值是啥意思?

如何在不使用 C++/C 中的阻塞函数的情况下将值从线程返回到主函数

如何从 char* 函数返回指针

从c ++中的函数返回数组向量[重复]

从 C 中的函数返回元组