【问题标题】:-Wcast-qual: cast discards ‘__attribute__((const))’ qualifier from pointer target type-Wcast-qual:cast 丢弃来自指针目标类型的“__attribute__((const))”限定符
【发布时间】:2017-10-31 23:22:02
【问题描述】:

代码:

static const char *a = NULL;
abc((char **)&a);

abc 方法定义为:

abc(char** a)

我收到错误(警告视为错误):

  error: cast discards '__attribute__((const))' qualifier from pointer target type [-Werror=cast-qual]

为了解决这个问题,我补充说:

#ifdef _PTR_CAST_
#define SIZE_T_CAST uintptr_t 
#else
#define SIZE_T_CAST size_t
#endif

我的问题是,api调用是否应该是

abc( (char **)(SIZE_T_CAST)&a); or
abc( (char **)(SIZE_T_CAST *)&a);

两者都没有抱怨,但正确的方法是什么?

【问题讨论】:

  • 首先,您可以尝试创建一个Minimal, Complete, and Verifiable Example 并展示给我们吗?然后还告诉我们在哪里你得到了错误?例如代码中的注释?
  • 我有所有可能解决这个问题的代码,这使得它非常完整和不言自明。
  • 好吧,那么...那么现在您必须告诉我们您是使用 C 还是 C++ 编程?这两种语言非常不同,即使它们有时看起来相同。我的猜测是您正在使用 C++ 编程,在这种情况下,您只需要一个 const_cast
  • 抱歉,我正在使用 C。我得到了 C++ 的建议,我添加了它。现已删除。
  • 那我真的不明白你会怎么得到那个警告? &a 是一个 const char **,您将其转换为 char ** 在 C 中一切正常。您确实abc 调用行上得到错误?不是别的地方吗?

标签: c gcc casting type-conversion


【解决方案1】:

首先,宏SIZE_T_CAST 是一个糟糕的主意。一开始就使用正确的类型。

代码(char **)(uintptr_t)&a(char **)(void *)&a 可能有效,尽管C 标准不保证。

但是,不使用演员表会更好的编码风格。而是制作一个包装函数,例如在你可以有的头文件中:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
inline void const_abc(const char ** p)
{
    abc( (char **)p );
}
#pragma GCC diagnostic pop

然后在其余代码中,当您有 const char ** 参数时调用 const_abc

See here 了解有关禁用代码特定部分的警告的更多信息。

【讨论】:

  • 能否请您帮助我了解 (char **)(uintptr_t)&a 和 (char **)(uintptr_t *)&a 在上述情况下有何不同?编译器不会抱怨两者,它编译时没有任何警告。
  • @CodeTry a 可能无法正确对齐 uintptr_t,并且在这两种情况下,标准都不能保证像这样的一系列强制转换会产生预期的结果(唯一的保证是往返转换回完全相同的类型)。如果您的第二个建议没有收到警告,请尝试使用void * 而不是uintptr_t *(无论如何使用uintptr_t * 没有多大意义)
  • 实际上是的, void * 应该可以工作。非常感谢您的宝贵时间。
猜你喜欢
  • 2023-03-18
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 2013-03-02
相关资源
最近更新 更多