【问题标题】:Intel C++ Compiler warning 167 when non-const argument is passed as const parameter [duplicate]当非 const 参数作为 const 参数传递时,英特尔 C++ 编译器警告 167 [重复]
【发布时间】:2013-02-15 18:35:14
【问题描述】:

我有一个大型代码库,最近从 Microsoft 的编译器转移到了英特尔 C++ 编译器。我们团队的目标是在主线中编译没有警告。自从切换以来,一个警告 167 的实例让我感到困惑。如果我编译以下代码:

int foo(const int pp_stuff[2][2])
{
   return 0;
}

int foo2(const int pp_stuff[][2])
{
    return 0;
}


int main(void)
{
    int stuff[2][2] = {{1,2},{3,4}};

    foo(stuff);
    foo2(stuff);

    return 0;
}

ICC 会给我警告:

1>main.c(17): warning #167: argument of type "int (*)[2]" is incompatible with parameter of type "const int (*)[2]"
1>        foo(stuff);
1>            ^
1>  
1>main.c(18): warning #167: argument of type "int (*)[2]" is incompatible with parameter of type "const int (*)[2]"
1>        foo2(stuff);

为什么这是一个警告?通常的做法是将非常量变量作为 const 参数传递,并且类型和维度是相同的。

对于那些将此问题标记为重复问题的人,我敦促您重新考虑。如果其他人遇到此警告,他们必须知道在 C 中参数是通过原型函数中的赋值进行转换的,然后搜索严格与赋值有关的问题。尽管答案最终与 C90/C99 中的子句相同,但我认为问题是完全不同的。

【问题讨论】:

  • 为什么不使用:int foo2(const int* pp_stuff)
  • @josh,因为它对其他开发人员的信息量不大。当我们传递固定维度的数组时,在声明中包含维度是自记录的。它还通过编译器警告/错误自我执行。

标签: c compiler-warnings icc


【解决方案1】:

将变量传递给需要 const 的函数时,将其转换为 const。

foo( (const int (*)[2]) stuff );

Why can't I pass a char ** to a function which expects a const char **?

Similar question

【讨论】:

  • 谢谢,我认为该链接回答了我的问题。
  • 所以我认为最好不要使用多维数组作为参数,而是使用指针数组,因为在这种情况下不需要强制转换。
【解决方案2】:

stuff 数组的值是 int (*)[2] 类型。

int foo(const int pp_stuff[2][2])

等价于

int foo(const int (*pp_stuff)[2])

在函数调用中,就好像您将 int (*)[2] 类型的值分配给 const int (*)[2] 类型的变量。

参数的转换就像通过原型函数中的赋值一样。如果满足以下条件,C 允许您分配两个指针:

两个操作数都是指向兼容类型的合格或不合格版本的指针,左边指向的类型具有右边指向的类型的所有限定符;

这里的int (*)[2]const int (*)[2] 不是同一类型的合格/不合格版本。限定符适用于int 而不是指针。

用途:

int foo(int (* const pp_stuff)[2])

如果你想创建指针 const 而不是 int 元素。

【讨论】:

  • 我仍然没有看到一个正确的理由来 not 将变量元素数组传递给一个函数,该函数告诉我它不会通过使其成为 const 来改变元素?
  • 在这个用例中,元素正是我想要的const。对我来说,这应该与将int 参数传递给const int 参数相同,它不会发出警告。如果我将声明 int foo3(const int (*const pp_stuff)[2]) {return 0;} 和关联的调用 foo3(p_stuff); 添加到 main(),我会收到另一个 167 警告。 (该版本也会触发 MS 智能感知错误。)但是,如果我使用 int foo3(const int *const pp_stuff[2]) {return 0;},警告就会消失。
  • @Phill 再次阅读规则,这不一样。您可以将int * 分配给const int *,因为intconst int 是同一类型的不合格/合格版本。 int (*)[2]const int (*)[2] 之间不是这种情况。
  • @Phill 还请注意,您的 foo3 示例与我的不同。
  • @ouah,有区别,我有一个额外的常量。然而,即使是更正的int foo4(int (*const pp_stuff)[2]) 也会导致 167 警告。我认为@Armin 链接的常见问题解答回答了这个问题,即使我希望不是这样。
猜你喜欢
  • 2012-02-25
  • 1970-01-01
  • 2014-09-03
  • 2016-05-29
  • 2020-07-13
  • 2017-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多