Является ли следующая программа строго соответствующей программой в C? Меня интересуют c90 и c99, но ответы c11 также приемлемы.
#include <stdio.h>
#include <string.h>
struct S { int array[2]; };
int main () {
struct S a = { { 1, 2 } };
struct S b;
b = a;
if (memcmp(b.array, a.array, sizeof(b.array)) == 0) {
puts("ok");
}
return 0;
}
В комментариях к моему ответу в другом вопросе, Эрик Postpischil настаивает, что выход программы будет меняться в зависимости от платформы, в первую очередь из-за возможности неинициализированных битов заполнения, Я думал, что назначение struct будет перезаписывать все биты в b
таким же, как в a
. Но C99, похоже, не предлагает такую гарантию. Из раздела 6.5.16.1 p2:
В простом присваивании (
=
) значение правильного операнда преобразуется в тип выражения присваивания и заменяет значение, хранящееся в объекте, обозначенном левым операндом.
Что означает "преобразованный" и "заменяет" в контексте составных типов?
Наконец, рассмотрим ту же программу, за исключением того, что определения a
и b
становятся глобальными. Будет ли эта программа строго соответствовать программе?
Изменить: Просто хотел обобщить часть материала для обсуждения здесь, а не добавить свой собственный ответ, так как у меня действительно нет одного из моих собственных творений.
- Программа не является строго соответствующей. Поскольку назначение выполняется по значению, а не по представлению,
b.array
может содержать или не содержать биты, отличные отa.array
. -
a
не нужно преобразовывать, так как он является тем же типом, что иb
, но замена производится по значению и выполняется членом пользователем. - Даже если определения в
a
иb
становятся глобальными, назначение post,b.array
может содержать или не содержать биты, отличные отa.array
. (Было мало обсуждений байтов заполнения вb
, но вопрос не касался сопоставления структуры. В c99 отсутствует упоминание о том, как заполнение инициализируется в статическом хранилище, но c11 явно заявляет, что инициализируется нулем.) - На стороне примечания есть согласие, что
memcmp
корректно определен, еслиb
был инициализированmemcpy
изa
.
Спасибо всем, кто участвовал в обсуждении.