Странный блок от массива, с 0 инициализациями

Docker прост, он просто запускает команды, которые вы ему даете, для базы изображений, с которой вы начинаете. Эта одна строка делает множество предположений, которые могут быть или не быть правдой:

  1. adduser установлено
  2. sudo установлено
  3. [112 ] настроен на разрешение корневых прав доступа для пользователей в группе sudo
  4. /bin/bash
  5. Вы уже создали /home
  6. Вы уже создал /home/$USERNAME

Если все эти предположения верны до этой строки RUN, то это может сработать, но, конечно, может быть другое предположение, которое я пропускаю.

28
задан Community 23 May 2017 в 10:30
поделиться

3 ответа

Причина строк 2 и 5 состоит в том, потому что Вы указали 0 в инициализаторе массива. Компилятор инициализирует все константы, затем увеличивают остальных использующих memset. Если бы необходимо было поместить два нуля в инициализатор, то Вы видели бы его strw (слово вместо байта) затем memset 8 байтов.

Что касается дополнения, это только используется для выравнивания доступов памяти - данные не должны использоваться при нормальных обстоятельствах, таким образом, memsetting это расточительно.

Редактирование: Для записи я могу быть неправ относительно strw предположения выше. 99% моего опыта ARM инвертируют код, сгенерированный GCC/LLVM на iPhone, таким образом, мое предположение не может перенести на MSVC.

14
ответ дан Cody Brocious 28 November 2019 в 03:42
поделиться

Оба бита кода являются bugfree. Эти две упомянутые строки не умны, но Вы просто доказываете, что этот компилятор испускает субоптимальный код.

Дополнительные байты обычно только инициализируются, если это упрощает блок или ускоряет код. Например, если у Вас есть дополнение между двумя заполненными нулями участниками, часто легче заполнить нулями дополнение также. Кроме того, если у Вас есть дополнение в конце, и Ваш memset () оптимизирован для многобайтовых записей, это может быть быстрее для перезаписи того дополнения также.

11
ответ дан MSalters 28 November 2019 в 03:42
поделиться

Некоторое быстрое тестирование указывает, что x86 компилятор Microsoft генерирует другой блок, если список инициализатора пуст, по сравнению с тем, когда это содержит нуль. Возможно, их компилятор ARM делает также. Что происходит, если Вы делаете это?

byte a[10] = { };

Вот протокол ассемблирования, который я получил (с опциями /EHsc /FAs /O2 на Visual Studio 2008). Обратите внимание, что включая нуль в списке инициализатора заставляет компилятор использовать невыровненные доступы памяти для инициализации массива, в то время как пустая версия списка инициализатора и memset() версия оба использования выровняла доступы памяти:

; unsigned char a[10] = { };

xor eax, eax
mov DWORD PTR _a$[esp+40], eax
mov DWORD PTR _a$[esp+44], eax
mov WORD PTR _a$[esp+48], ax

; unsigned char b[10] = { 0 };

mov BYTE PTR _b$[esp+40], al
mov DWORD PTR _b$[esp+41], eax
mov DWORD PTR _b$[esp+45], eax
mov BYTE PTR _b$[esp+49], al

; unsigned char c[10];
; memset(c, 0, sizeof(c));

mov DWORD PTR _c$[esp+40], eax
mov DWORD PTR _c$[esp+44], eax
mov WORD PTR _c$[esp+48], ax
8
ответ дан bk1e 28 November 2019 в 03:42
поделиться