考虑以下代码,这是从这个问题中提出来的:
当我们添加
const int (*foo(const char *a))[1]
{ return (const int (*)[1]) a; }
当使用-Wcast-qual
编译GCC 8.2(以及旧版本)时,GCC会发出警告:
source>:2:15: 警告:从指针目标类型中丢弃'const'限定符 [-Wcast-qual] { return (const int (*)[1]) a; } ^
这个警告正确吗?显然,目标类型中有一个const
限定符。
它在元素类型上而不是指针直接指向的东西上,即数组类型。但是,即使我们使用typedef int T [1];
并将转换替换为(const T *)
,警告仍然存在。此外,根据C 2018 6.7.3 10,数组类型上的限定符应用于元素类型,而不是数组类型,因此两种方法的类型相同。
Clang没有显示此警告。
如果我们将转换更改为(const void *)
:
const int (*foo(const char *a))[1]
{ return (const void *) a; }
当我们添加
-pedantic
到编译开关时,警告消失了。如果我们将其添加,则会得到一个有关const
的不同警告:
source>:2:15: warning: return discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] { return (const void *) a; } ^~~~~~~~~~~~~~~~这看起来像是相同的警告,只是它是关于从返回表达式到函数返回类型的隐含转换,而先前的警告则是关于强制转换中的显式转换。但是,这个警告仅在使用
-pedantic
时出现。为什么?
char
的指针更改为int
会引发对齐问题。 - chux - Reinstate Monicahandle_warn_cast_qual
中会生成此警告,在两行代码中,它们说discarded |= (TYPE_QUALS_NO_ADDR_SPACE (in_otype) & ~TYPE_QUALS_NO_ADDR_SPACE (in_type));
。您需要深入了解in_otype
,以查看它是否为数组类型,并且元素类型是否设置了其base.readonly_flag
位。 - zneak(int (*)[1])(const int(*)[1])42;
жҲ–иҖ…typedef int T[1]; (T*)(const T*)42;
еҸҜд»Ҙж¶ҲйҷӨconst
е…ій”®еӯ—пјҢеңЁgccе’Ңclangзј–иҜ‘еҷЁдёҠйғҪжІЎжңүиӯҰе‘ҠгҖӮ - KamilCukint main(void) { const char *a = 0; (const int (*)[1])(a); }
- M.M