LINUX.ORG.RU

const type var = value vs #define var value

 


1

2

Я тут читаю умную книжку и автор уверенно заявляет, что #define для лох^W сишников, а плюсовики должны использовать const type var = 0;
А у меня уши растут с Си и поэтому у меня вопрос к тем, у кого сильна теоретическая плюсовая база.
Если с #define всё ясно — препроцессор просто пробежится по тексту, то с константой у меня вопрос. Будет ли выделяться под неё память? В принципе компилятор вполне может выполнить работу препроцессора и заменить встречающуюся константу на её значение. В идеале мы получим и проверку типа и никаких накладных расходов.
Или я что-то упускаю? Или я всё правильно думаю, но компилятор всё равно всё сделает через жопу?
Расскажите.

Перемещено mono из talks

★★☆

Будет ли выделяться под неё память?

ЕМНИП на усмотрение компилятора. Может и выделит, а может и на литералы везде заменит

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

+1 к

ЕМНИП на усмотрение компилятора. Может и выделит, а может и на литералы везде заменит

Но на практике, если ты не берешь адрес (или ссылку) и значение доступно (т.е. не в другом .cpp), то подставит.

Еще более на практике - тебе пох на 4 байта и не морочь себе голову.

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

если ты не берешь адрес (или ссылку)

Дык в том-то и дело что я могу (не особо могу придумать зачем, но могу). И не думаю, что компилятор будет заморачиваться анализировать весь код чтобы понять как я эту константу использую. Т.е. он создаст полноценную переменную.

тебе пох

Слушай, я и так распиздяй каких мир не видывал. Дай мне хоть чуть-чуть поперфекционировать. А надо бы провести эксперимент. Гм...

Stahl ★★☆
() автор топика

Если константа целочисленная, то можно enum { var = value }, тогда память никогда не будет выделяться. Вообще const на глобальном уровне всегда получают неявный static, поэтому может быть ситуация, когда куча объектных файлов содержат одно и то же. Тут («сцена седьмая») написано:

О том, что значит «static» в «const», я узнал несколько лет назад, когда меня попросили выяснить, почему одна из наших ключевых библиотек DLL вдруг прибавила в весе 2 МБ. Оказывается, в заголовочном файле был массив констант, и мы получили тридцать копий этого массива в DLL. То есть иногда это все же имеет значение.
Так что совсем много констант писать не нужно, компилятор может удалить, но может и оставить.

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

Дык в том-то и дело что я могу (не особо могу придумать зачем, но могу). И не думаю, что компилятор будет заморачиваться анализировать весь код чтобы понять как я эту константу использую. Т.е. он создаст полноценную переменную.

После какого-то этапа у компилятора на руках use-list каждой переменной. Если в процессе оптимизаций, например, после constant folding (и других, просто эта тут просится) список пустеет, то пропадает даже смысл хранить информацию о ней и можно сразу же забыть и в объектный файл не вставлять. Так что это не сложно сделать компилятору.

xaizek ★★★★★
()
Последнее исправление: xaizek (всего исправлений: 1)
Ответ на: комментарий от xaizek

enum { var = value }

Ну так #define приятней. Мне, во всяком случае. А с проверкой типов они одинаково бесполезны.

Так что это не сложно сделать компилятору.

Надо проводить эксперимент. Добавить немного типов там, где их не было (точнее где они были отфонарными) это всего хорошо.

Stahl ★★☆
() автор топика
Ответ на: комментарий от Pavval

Еще более на практике - тебе пох на 4 байта и не морочь себе голову.

Только вот если система embedded и таких констант несколько сотен, уже совсем не пох :)

В своей практике встречал уважаемого программиста с 30+ годами опыта, который в коде писал для констант define и только define, а на вопрос, почему не const T, смело, открыто и прямо в лицо сообщал, что «они же память жрут!».

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

ко всему сказанному выше const type - type-safe

anonymous
()
Ответ на: Тред не читал от Stil

constexpr

Гм. Да, это то, что нужно. И память на месте и проверка на типы присутствует.
Тему можно, в принципе, закрывать.

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

константы можно вкладывать в неймспейсы или любые операторные скобки вообще. отладка проще т.к. можно принтануть константку.

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

А с проверкой типов они одинаково бесполезны.

$ cat q.c
enum n {
 FIRST,
 SECOND,
 THIRD
};

int f(enum n a) {
 switch (a) {
  case FIRST: return 1;
  case SECOND: return 2;
 }
 return -1;
}

$ gcc -c -Wall q.c
q.c: In function ‘f’:
q.c:8:2: warning: enumeration value ‘THIRD’ not handled in switch [-Wswitch]
  switch (a) {
  ^
$ 
i-rinat ★★★★★
()
Ответ на: комментарий от Stahl

Дык в том-то и дело что я могу (не особо могу придумать зачем, но могу). И не думаю, что компилятор будет заморачиваться анализировать весь код чтобы понять как я эту константу использую. Т.е. он создаст полноценную переменную.

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

asaw ★★★★★
()

В принципе компилятор вполне может выполнить работу препроцессора и заменить встречающуюся константу на её значение.

Нормальный компилятор так и сделает

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

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

Ну если тебе оно надо, то как собираешься дефайнами обходиться?

Ну и сейчас модно вообще constexpr.

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

const умеет в scope, #define — нет.

В теории да, на деле там, где используют #define для задания переменных scope не имеет значения.

По мне так можно использовать и то и другое и constexpr.

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

Т.к. ТС надо С++, то можно использовать enum class и тогда не надо никакого -Wall и компилятор выдаст ошибку, а не предупреждение.

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

При условии что оно поддерживается компилятором. В привет, VS 2013!

constexpr:
VS 2013         : NO
VS 2015 Preview : PARTIAL

Я восхищён их слоупочеством!

Остальная часть сообщения целиком [5.1] :(

Stil ★★★★★
()

А const и в сях работает.

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

Вот это кстати заблуждение. На халяву ничего не бывает. Да, define'ы не жрут DRAM, зато жрут IRAM, так как иммедиатс пакуются прямо в иструкцию. Особенно на x86 это чувствуется.

rha
()
Ответ на: комментарий от Kroz

При условии что оно поддерживается компилятором. В привет, VS 2013!

Кстати они всё-таки её осилили

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