LINUX.ORG.RU

Constants in C: #define vs. const


0

0

#define SOME_CONST "String constant."

vs.

const char *const some_const = "String constant.";

Практически во всех виденных мной программах на C константы задаются первым методом (т.е. через препроцессор). Почему? И чем первый метод лучше второго?

Deleted

Потому что const-а раньше не было.

Ничем не лучше, второй лучше, т.к. он syntax aware. Ну, разве что, чисто теоретически, глупый компилятор может не подставить цифры, а использовать read-only переменные.

Legioner ★★★★★
()
Ответ на: комментарий от andreyu

>> Если верить Б. Страуструпу, то в C++ первый метод depricated.

Это я знаю, вопрос именно про C.

Deleted
()

> И чем первый метод лучше второго?

компилятор имеет право смержить строковые литералы -- т.е. это в первом случае.

Во втором случае, разные объекты обязаны иметь разные адреса, поэтому мерж запрещен.

dilmah ★★★★★
()

Потому что const-переменные в общем случае должны находится в памяти как реальные объекты. У них можно брать адрес, разыменовывать указатели и т.п.

В C++ есть ключевое слово "mutable", которое очень наглядно компрометирует "const" для структур.

anonymous
()
Ответ на: комментарий от Legioner

изменение - да, но чтение через указатель разрешено

anonymous
()
Ответ на: комментарий от dilmah

может , область видимости и выделение памяти как-то по-разному работают ?

kto_tama ★★★★★
()
Ответ на: комментарий от dilmah

> Во втором случае, разные объекты обязаны иметь разные адреса, поэтому мерж запрещен.

Мне казалось, во втором случае(глоб. константа) как раз и будет одна копия объекта т.к. будет один symbol константы.

> Ну, разве что, чисто теоретически, глупый компилятор может не подставить цифры, а использовать read-only переменные.

Imho если это не влияет на логику отбрасывания кода эти два варианта монопенисуальны. Т.к. во втором случае константа(если уж об int-ах речь) будет зашита в сегмент кода и точно так-же будет считываться из памяти.

YesSSS ★★★
()
Ответ на: комментарий от YesSSS

>Imho если это не влияет на логику отбрасывания кода эти два варианта монопенисуальны. Т.к. во втором случае константа(если уж об int-ах речь) будет зашита в сегмент кода и точно так-же будет считываться из памяти.

В первом варианте процессор сразу вытащит операнд (да и команда другая). Во втором варианте он вытаскивает указатель, делает запрос к памяти, ждёт до 500 тактов, пока эта память отзовётся и вернёт значение и потом уже выполняет операцию. Поэтому разница есть.

Legioner ★★★★★
()
Ответ на: комментарий от YesSSS

1. Это тупо исторически сложилось так.

2. #DEFINE фактически объявляет макрос. в нем может быть хоть кусок кода. То, что ты определил define'om заменяется во всех местах на значение еще препроцессором, в то время как второй вариант работает уже потом, в откомпилированной программе и является фактически неизменяемой переменной. Отсюда остальные ответы на твои "почему".

name_no ★★
()
Ответ на: комментарий от Legioner

Проблема в том, что перейти с одного mpi на другой без перекомпиляции не получится, хотя либа и чисто сишная. Вот если бы эти константы(разные у разных вендоров) не инлайнились в твой код...

YesSSS ★★★
()
Ответ на: комментарий от Legioner

Да я понимаю, так, высказался о наболевшем. =)

YesSSS ★★★
()

Я всегда пользуюсь #define по следующим причинам: 1. Не все компиляторы C поддерживают const, хотя это решается autotoolsами. 2. Я всегда могу определить есть ли такая константа. Например: #ifdef SIGINT signal(..) #endif В Windows сигналов мало, соответственно такими ifdefами я делаю кросс-платформенный код :)

rymis ★★
()
Ответ на: комментарий от YesSSS

> Мне казалось, во втором случае(глоб. константа) как раз и будет одна копия объекта т.к. будет один symbol константы.

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

#define MESSAGE32 "UNIMPLEMENTED"
#define MESSAGE666 "UNIMPLEMENTED"

dilmah ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.