Я предполагаю, что вопрос здесь «Почему это? / Что дает?».
В этом случае это действительно небольшая проблема в разработке стандартов / гибкости для разработчиков компиляторов.
Строго говоря, *(void*)
всегда плохо, и компилятор правильно предупредит вас.
На практике, как вы правильно заметили, указатель на самом деле никогда не разыменовывается, при оценке того, что вы видите на то, на что он указывает, таким образом, у наивной реализации компилятора не будет проблем с тем, чтобы увидеть это так, как вы делаете, и замаскировать это и говорит «указатели: они числа правильно? это 0xFFF ....».
На практике, хотя иногда это не так. Иногда компиляторы становятся довольно умными. Нет хороших примеров, но это не главное.
Несколько вещей, которые, я думаю, стоит отметить в отношении «это никогда не оценивается»:
Причина, по которой компиляторам предоставляется свобода делать то, что они хотят, отчасти облегчает сам процесс компиляции, а не только выводит лучшие реализации.
Возможно, следующий компилятор, на который вы указываете, скажет «нет». Просто потому, что так проще и не нужно.
Во-вторых, на самом деле это не точка предупреждений. Если я видел это в обзоре кода:
int i = 3;
if (3-i) {
((int*)(NULL)) += 4;
}
моя реакция будет не : "О, хорошо, все в порядке, это не оценено". но "Вау, подожди секунду: почему?" Это то, что делает компилятор тоже. Он говорит вам, что думает, что вы, вероятно, сделали что-то, что вы, возможно, захотите пересмотреть, в этом случае называя const char *
a void *
. Я, например, согласен с GCC.