【问题标题】:Const return types in CC 中的 const 返回类型
【发布时间】:2010-08-22 14:09:29
【问题描述】:

我正在阅读一些代码示例,它们返回了一个 const int。当我尝试编译示例代码时,我收到了有关返回类型冲突的错误。所以我开始搜索,认为 const 是问题所在(当我删除它时,代码工作正常,不仅编译,而且按预期工作)。但是我从来没有找到与 const 返回类型相关的信息(我为结构/参数/等找到了信息,但没有找到返回类型)。所以我试着写一段代码来简单地展示 const 可以做什么。我想出了这个:

#include <stdio.h>

int main() {
    printf("%i", method());
}

const int method() {
    return 5;
}

当我编译这个时,我得到:

$ gcc first.c 
first.c:7: error: conflicting types for ‘method’
first.c:4: note: previous implicit declaration of ‘method’ was here

但是,每当我删除 const 时,它就像预期的那样简单地打印出一个 5,a 继续生活。那么,谁能告诉我 const 在用作返回类型时应该是什么意思。谢谢。

【问题讨论】:

  • 在这个例子中,问题是不同的:你在声明之前使用了method(),所以隐式假设它返回一个int。依赖这种过时的行为是一个坏主意。更改您的示例以将 method() 声明为返回 const int 以使其更具代表性。换句话说,这里的const 和非const 类型之间存在标准冲突,const 类型是函数返回的类型这一事实无关紧要。
  • gcc 是否还有 -ansi-pedantic 选项?对于新代码,这可能是强制性的。
  • Meta-pedantic: -ansi-pedantic 是单独的选项 ;-)
  • meta-meta-pedant:pedantic 正在检查标准的一致性,C 标准包括“过时”的行为。
  • 好的,我已经很久没有关心了,但我很确定有一个选项可以强制使用原型。那不是-ansi吗?

标签: c constants


【解决方案1】:

const 对返回值没有意义,因为返回值在任何情况下都是 rvalues 并且不能被修改。您得到的错误是因为您在声明之前使用了一个函数,因此隐式假定它返回int,而不是const int,但是当实际定义该方法时,返回类型不匹配原来的假设。如果返回 double 而不是 int,你会得到完全相同的错误。

例如:

#include <stdio.h>

int main() {
    printf("%i", method());
}

double method() {
    return 5;
}

生成:

$ gcc -std=c99 -Wall -Wextra -pedantic impl.c
impl.c: In function ‘main’:
impl.c:4: warning: implicit declaration of function ‘method’
impl.c: At top level:
impl.c:7: error: conflicting types for ‘method’
impl.c:4: note: previous implicit declaration of ‘method’ was here

看看提高警告级别有多大帮助!

【讨论】:

    【解决方案2】:

    在调用之前添加 method() 的原型将修复错误。

    const int method();
    int main() {
        printf("%i", method());
    }
    

    Line 7: error: conflicting types for 'method'
    

    这个错误告诉我们method() 是由编译器创建的(因为它没有找到它),它的返回类型不同于const int(可能是int)。

    Line 4: error: previous implicit declaration of 'method' was here
    

    另一个错误告诉我们,实际上编译器创建了自己的method 版本。

    【讨论】:

    • 是的,它奏效了。谢谢你。我从未意识到,当方法位于使用它们的位置时,GCC 会创建它们。我想这是为什么头文件通常包含在源代码中的另一个原因......谢谢。
    • 您在调用之前没有添加任何原型。这是一个没有原型的声明。
    • 应该是:const int method(void);而不是 const int method(); ?
    • @LeifAndersen 是的。
    【解决方案3】:

    您发布的代码至少应该给您一个未定义的标识符:method。在调用函数之前,您需要在范围内声明。更好的使用:

    #include <stdio.h>
    
    const int method() {
        return 5;
    }
    
    int main() {
        printf("%i", method());
    }
    

    定义也是声明。因此,这应该可以解决您的错误。

    【讨论】:

    • 谢谢,我把原型放上去,问题解决了。
    • 与 gcc 一起使用的一组很好的选项是:-Wall -ansi -pedantic -std=c99。也可以在 GCC 的文档中查找其他文档。
    • @dirkgently: -ansi 等价于-std=c89-std=c99 一起使用没有意义。
    • 为什么要投票?这是错误的,因为 C 在看到看起来像函数调用的未定义标识符时不会出错。它只是假设函数是 int() 类型的。
    • @dirkgently 据我所知,ANSI C 只是在注释上有所不同,没有规范的措辞(我记不太清了)。有链接吗?
    【解决方案4】:

    在你向 C 充分了解函数之前,当你使用函数时,C 会猜测函数的返回类型——它是名称、返回类型、常量和参数。如果这些猜测是错误的,你就会得到错误。在这种情况下,他们错了。使用原型或将函数移到调用之上。

    哦,关于 CONST 属性: 这意味着如果您使用相同的参数再次调用一个函数,它的值将是相同的,并且应该没有(重要的)副作用。这对于优化很有用,并且它还提出了编译器可以强制执行有关参数的文件声明。函数承诺不会改变常量,编译器可以帮助阻止它。

    【讨论】:

    • 您能否提供一个参考,说明 const 限定的返回类型意味着函数具有纯行为,即它为相同的输入值产生相同的返回值?我从来没有听说过。
    • ohse.de/uwe/articles/gcc-attributes.html#func-const 诚然,这是 GNU 文档而不是标准,但它应该能让你继续前进。我是从 Borland 的 C++ 编译器附带的书籍中学到的,早在 Windows 成为强制性之前。
    • +1 用于提及返回值的真正 const 解释。你应该提到在使用 gcc 时最好使用__attribute__ ((const))__attribute__ ((pure))。恕我直言,更明确。
    • 这是不同的东西,甚至那个页面最后也是错误的。该语言规定不得在函数类型上指定const。该语言完全允许它在返回类型上。该页面的示例将其应用于函数类型(即应用于函数的类型,not 应用于返回类型的类型,如最后的文本声明)。更具体地说,C 将其呈现为未定义的行为,而 C++ 完全禁止它,尽管 C++0x 放宽了规则并说 const 只是被忽略了。
    • 我认为您混淆了 C++ const 成员函数(它使用与此不同的语法 - 最后是 const。)您在这里所做的是声明返回的值是不可修改的。返回值始终是 C 中的右值,而 C 中的右值 never 不可修改,因此实际上这里的 const 是无用的。要验证这一点,只需获取最新版本的 llvm(可能还​​有 GCC)并使用 -Weverything 标志编译它,编译器会给你一个警告......
    【解决方案5】:

    main 看到 method() 没有原型的使用,所以它假定它返回 int。然后你声明它返回const int。将method()的声明移到main之前,或者在main之前放一个原型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多