При обнулении структуры, такой как sockaddr_in, sockaddr_in6 и addrinfo перед использованием, которое корректно: memset, инициализатор или также?

Только для примера:

Я выполнял запрос ниже в MySQL Workbench & amp; Я нашел свой файл в

SELECT * FROM `db`.`table` INTO OUTFILE 'file.csv' FIELDS TERMINATED BY ',';

D: \ wamp \ bin \ mysql \ mysql5.6.17 \ data \ db \ file.csv

Вы можете использовать приведенный ниже пример, чтобы установить путь к файлу:

SELECT * FROM `db`.`table` INTO OUTFILE 'C:\\file.csv' FIELDS TERMINATED BY ',';
22
задан Chris Young 21 May 2009 в 18:15
поделиться

4 ответа

Одна проблема с подходом частичных инициализаторов (то есть ' {0} ') заключается в том, что GCC предупредит вас, что инициализатор неполный (если уровень предупреждения высокий достаточно, я обычно использую « -Wall » и часто « -Wextra »). При подходе с назначенным инициализатором это предупреждение не должно выдаваться, но C99 по-прежнему широко не используется - хотя эти части довольно широко доступны, за исключением, возможно, мира Microsoft.

Я склонен используется в пользу подхода:

static const struct sockaddr_in zero_sockaddr_in;

За ним следует:

struct sockaddr_in foo = zero_sockaddr_in;

Отсутствие инициализатора в статической константе означает, что все равно нулю, но компилятор не будет мерцать (не должен мерцать). Присваивание использует копию внутренней памяти компилятора, которая выиграла ' t быть медленнее, чем вызов функции, если только компилятор не имеет серьезных недостатков.


GCC изменился с течением времени

GCC версии 4.4.2–4.6.0 генерируют предупреждения, отличные от GCC 4.7.1. В частности, GCC 4.7.1 распознает инициализатор = {0} как «особый случай» и не жалуется, тогда как GCC 4.6.0 и т. Д. Жаловался.

Рассмотрим файл init. c :

struct xyz
{
    int x;
    int y;
    int z;
};

struct xyz xyz0;                // No explicit initializer; no warning
struct xyz xyz1 = { 0 };        // Shorthand, recognized by 4.7.1 but not 4.6.0
struct xyz xyz2 = { 0, 0 };     // Missing an initializer; always a warning
struct xyz xyz3 = { 0, 0, 0 };  // Fully initialized; no warning

При компиляции с GCC 4.4.2 (в Mac OS X) появляются следующие предупреждения:

$ /usr/gcc/v4.4.2/bin/gcc -O3 -g -std=c99 -Wall -Wextra -c init.c
init.c:9: warning: missing initializer
init.c:9: warning: (near initialization for ‘xyz1.y’)
init.c:10: warning: missing initializer
init.c:10: warning: (near initialization for ‘xyz2.z’)
$

При компиляции с GCC 4.5.1 предупреждения:

$ /usr/gcc/v4.5.1/bin/gcc -O3 -g -std=c99 -Wall -Wextra -c init.c
init.c:9:8: warning: missing initializer
init.c:9:8: warning: (near initialization for ‘xyz1.y’)
init.c:10:8: warning: missing initializer
init.c:10:8: warning: (near initialization for ‘xyz2.z’)
$

При компиляции с GCC 4.6. 0 предупреждения:

$ /usr/gcc/v4.6.0/bin/gcc -O3 -g -std=c99 -Wall -Wextra -c init.c
init.c:9:8: warning: missing initializer [-Wmissing-field-initializers]
init.c:9:8: warning: (near initialization for ‘xyz1.y’) [-Wmissing-field-initializers]
init.c:10:8: warning: missing initializer [-Wmissing-field-initializers]
init.c:10:8: warning: (near initialization for ‘xyz2.z’) [-Wmissing-field-initializers]
$

При компиляции с GCC 4.7.1 предупреждения следующие:

$ /usr/gcc/v4.7.1/bin/gcc -O3 -g -std=c99 -Wall -Wextra  -c init.c
init.c:10:8: warning: missing initializer [-Wmissing-field-initializers]
init.c:10:8: warning: (near initialization for ‘xyz2.z’) [-Wmissing-field-initializers]
$

Компиляторы, указанные выше, были скомпилированы мной. Компиляторы, предоставляемые Apple, - это номинально GCC 4.2.1 и Clang:

$ /usr/bin/clang -O3 -g -std=c99 -Wall -Wextra -c init.c
init.c:9:23: warning: missing field 'y' initializer [-Wmissing-field-initializers]
struct xyz xyz1 = { 0 };
                      ^
init.c:10:26: warning: missing field 'z' initializer [-Wmissing-field-initializers]
struct xyz xyz2 = { 0, 0 };
                         ^
2 warnings generated.
$ clang --version
Apple clang version 4.1 (tags/Apple/clang-421.11.65) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.4.2
Thread model: posix
$ /usr/bin/gcc -O3 -g -std=c99 -Wall -Wextra -c init.c
init.c:9: warning: missing initializer
init.c:9: warning: (near initialization for ‘xyz1.y’)
init.c:10: warning: missing initializer
init.c:10: warning: (near initialization for ‘xyz2.z’)
$ /usr/bin/gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$

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

Не существует единого краткого ответа. ... там, наверное, никогда не было, и нет сейчас.

14
ответ дан 29 November 2019 в 05:38
поделиться

"struct sockaddr_in foo = {0};" действительно только в первый раз, тогда как "memset (& foo, 0, sizeof foo);" будет очищать его каждый раз при запуске функции.

3
ответ дан 29 November 2019 в 05:38
поделиться

При любом подходе проблем быть не должно - значения байтов заполнения не должны иметь значения. Я подозреваю, что использование memset () проистекает из более раннего использования берклиевского bzero (), которое могло предшествовать введению инициализаторов структур или было более эффективным.

1
ответ дан 29 November 2019 в 05:38
поделиться

Как многие отмечали, верен любой из них. Кроме того, вы можете выделить эти структуры с помощью calloc , который уже возвращает обнуленный блок памяти.

1
ответ дан 29 November 2019 в 05:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: