> Мне интересен стандарт, а не придумщики этих языков. > Часто, то, что мы используем, и то, что норма для > партикулар компилер - вовсе не стандарт. > Например, void main (void) - норма для Borland & > Microsoft. Но это нарушение стандарта.
Все верно, но не совсем. main это
#ifdef __cplusplus
extern "C"
#endif
int main(int argc, char *arvg[]);
То бишь соглашение о линковке - сишное. Таким образом линкер видит только _main, рантайм честно разрезает командную строку на argc/argv и передает в main, только они не используются, а в качестве возвращаемого значения в тот же msvc/x86 (в других компиляторах - аналогично) использует тот мусор, который окажется в eax на момент выхода. Кроме того, стандарт не говорит о том, чтобы функция main была ОБЪЯВЛЕНА где либо в стандартной библиотеке (чтобы повторное объявление с другими типами вызывало ошибку). Короче, ЛЮБОЙ стандартный компилятор не должен давиться от
void main(void)
> > Например для связки AMD/GCC структура, состоящая из > трех > > однобайтовых элементов может быть расширена до > > четырехбайтового размера.
> 1) практическивсегдабудет расширена. выравнивание по > границе байта очень редко используется; и, думаю, никогда > по умолчанию.
Не совсем так. Выравнивание для байта - 1, для слова - 2 и т.д., таким образом
struct {char a, b, c};
практически никогда не будет расширяться, если не задать явный алигн. Надо понимать, что место добавляется не ПОСЛЕ элемента, а ПЕРЕД. То бишь байту по фигу куда размещаться, а вот если после байта идет long, то появится дырка для алигна. Причем структура как бы зациклена (как раз чтобы не возникало проблем с массивами). То бишь, после последнего элемента добавляется столько места, чтобы нормально выравнять первый.
#include "stdio.h"
struct test1 {
char c1, c2, c3;
};
struct test2 {
long l;
char c;
};
struct test3{
long double l;
char c;
};
int
main() {
printf("%d\t%d\n", sizeof(struct test1), sizeof(struct test1[10]));
printf("%d\t%d\n", sizeof(struct test2), sizeof(struct test2[10]));
printf("%d\t%d\n", sizeof(struct test3), sizeof(struct test3[10]));
return 0;
} ---
даст
3 30
8 80
16 160 ---
> 2) > struct __declspec(align(32)) a > { > byte val3; > WORD val4; > }; > > sizeof вообще вернёт 32 байта ;)
> > Размер структуры должен учитывать все "дырки" для > > правильного динамического выделения памяти для масива > > структур. > > Ты не прав здесь немного, имхо. Опреции с памятью всегда > будут коректными, если используешь sizeof. > sizeof всегда вернёт тебе правильное значение размера > структуры, независимо от выравнивания структуры по границе > байта, слова и т.д. Важно здесь другое - не делать сильных > предположений о размере структуры (типа #define > STRUCTURE_SIZE .... ) при распределении памяти, или > навигации внутри массивов.
Навигация внутри массива - вполне безопасное действие, а вот в остальном - согласен. Вместо STRUCTURE_SIZE надо использовать sizeof(structure), а вместо жестко заданного смещения, макрос типа
#define OFFSET_OF(type, field) ((unsigned long)(((type *)0)->field))
> ПС. В контексте топика. amirul прав, на мой взгляд. "дыры" > всегда будут покрыты 0 memset-ом, если использовать sizeof > для всей структуры.
|