sizeof(void())是一个合法的表达式吗?

时间:2016-09-01 18:06:00

标签: c++ language-lawyer sizeof void

[5.3.3/1],我发现:

  

sizeof运算符不应用于具有函数或类型不完整的表达式

[3.9/5]我发现:

  

未完全定义的对象类型和cv void是不完整的类型

无论如何,因为sizeof(void())没有评估它的操作数,我会说void是一个合法的表达式(实际上GCC编译它,结果是1)。
另一方面,从here开始,在讨论sizeof时未提及sizeof(void()),既没有提到大小为1的类型,也没有提及的类型实现定义大小。

问题是:defines = ["FEATURE_A"] if somehow_detect_the_platform == 'ios': defines.extend("FEATURE_B") cc_library( name = "foo", srcs = ["foo.cc"], defines = defines, hdrs = ["foo.h"], ) 是一个法律表达吗? 是否保证大小等于1? 或者它是一个导致UB的法律表达,这就是全部?

6 个答案:

答案 0 :(得分:58)

void()是一个函数类型(它是一个不带参数且不返回任何内容的函数),因此它不是sizeof()中的有效类型。

答案 1 :(得分:40)

通过查看CppReference.com - sizeof operator,文档字面上指出:

  

sizeof不能与功能类型,不完整类型或   位字段glvalues。

由于void()是函数类型,因此sizeof(void())不是合法表达式。

在他们的使用示例中,我们可以在此行上看​​到他们的错误评论:

std::cout << "size of function: " << sizeof(void()) << '\n'; // error

答案 2 :(得分:9)

此外,如果您编译代码,例如下面的示例:

#include <iostream>

int main()
{
   std::cout << sizeof(void());
}

代码正确编译并生成值1,但是如果你看一下编译,你会看到:

  

main.cpp:在函数'int main()'中:

     

main.cpp:5:29:警告:'sizeof'无效应用于函数类型[-Wpointer-arith]

     

std :: cout&lt;&lt;的sizeof(无效());

因此,很明显sizeof()不适用于函数类型,因此代码会产生警告。它无效。

<小时/> Code here

答案 3 :(得分:6)

一个小前提。

问题产生于对sizeof运营商的误解 事实上,OP在void()的上下文中考虑了sizeof表达式不完整的表达式,问题本身可以理解为 - 为什么sizeof接受表达式void() },这是一种不完整的类型,不应该像工作草案中提到的那样被接受? 这就是实际提到[3.9 / 5]的原因,否则它就没有意义了。

那就是说,事实是这个问题实际上包含两个有趣的问题:

  • 为什么sizeof(void())不合法?
    这是标题本身的实际问题。

  • 为什么sizeof((void()))不合法?
    这是OP的预期问题。

以下答案:

    {li>

    void()中的sizeof(void())被解释为一种函数类型,而[5.3.3/1]的格式不正确(强调我的):

      

    sizeof运算符不应该应用于具有或不完整类型的表达式到此类型的带括号的名称,[...]

    {li>

    (void()) sizeof((void()))中的void是一个表达式sizeof不完整(注意var viewModel = $("#myFormId").serializeObject(); var request = $.ajax({ url: '@Url.Action("UpdateAction", "SomeController")', type: "POST", cache: false, data: viewModel, datatype: "json" }) request.done(function (data) { $.each(data, function (key, value) { $("#myFormId) input[name=" + key + "]").val(value); }); }) 是一个未评估的上下文)并且它的格式不正确[5.3.3/1](强调我的):

      

    sizeof运算符不应该应用于具有功能或不完整类型的表达式,这些类型的带括号的名称,[...]

在这两种情况下,GCC都会用警告编译代码。

答案 4 :(得分:1)

正如此文档http://en.cppreference.com/w/cpp/language/sizeof

中已经强调的那样

备注

sizeof()不能与函数类型,不完整类型或位字段glvalues一起使用。

由于void()是函数类型,因此它不是sizeof()的有效类型

注意:

void()是一个不带参数且不返回任何内容的函数

从文档中引用示例:

//<< "size of function: " << sizeof(void()) << '\n'  // error

回答你的问题:

1)不,这不是法律表达。

2)它将显示为1,但会显示警告

3)与1)相同。

答案 5 :(得分:1)

来自C99参考NO的Straigth

6.5.3.4 sizeof运算符

部分的文件中说明
  

sizeof运算符不应该应用于具有函数类型或不完整类型的表达式,这种类型的带括号的名称,或者应用于指定位字段成员的表达式。

根据 6.2.5类型

部分的第19和20项
  
      
  1. void类型包含一组空值; 它是一个不完整的类型无法完成。
  2.   
  3. ...函数类型描述具有指定返回类型的函数。函数类型的特征在于其返回类型以及其参数的数量和类型。   函数类型据说是从它的返回类型派生的,如果它的返回类型是T,函数类型有时被称为''函数返回T''。从返回类型构造函数类型称为“函数类型派生”。
  4.   

因此,void()是从不完整类型派生的函数类型,并且它作为sizeof的操作数非法。这表示它的返回将取决于编译器的实现,并且没有任何保证的返回值

C99 Standard