Оператор .
имеет более высокий приоритет , чем приведение в стиле C. Таким образом, *(struct S*)p.val
рассматривается как *((struct S*)(p.val))
, что не имеет смысла, поскольку p
является указателем и не имеет членов.
Таким образом, вам нужно скобки, чтобы указать, что вы хотели:
std::cout<< (*(struct S*)p).val << std::endl;
Или, что эквивалентно,
std::cout<< static_cast<S*>(p)->val << std::endl;
[Но также: оператор *(struct S*) p = s;
технически имеет неопределенное поведение, даже если все большинство реализаций позволят это. Это связано с тем, что в C ++ есть правила о том, когда создается объект, и ранее по этому адресу не было объекта типа S
, а присваивание не создает объект, за исключением некоторых случаев, в которых участвуют члены объединения. Подобное утверждение, у которого нет этой проблемы, было бы new(p) S{s};
.
Также также: использование malloc
или void*
обычно не очень хорошая идея для C ++. malloc
следует использовать только при взаимодействии с библиотекой C, которая этого требует. Все, для чего void*
кажется полезным, может быть сделано более безопасно с использованием шаблонов. В некоторых случаях void*
может быть единственным способом что-то сделать или «умно» избежать дублирования кода или чего-то еще, но все равно использовать его экономно и всегда с особой осторожностью.]