Форум программистов, компьютерный форум CyberForum.ru

Чем же макрос define так плох? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 52, средняя оценка - 4.90
ertyuo
0 / 0 / 0
Регистрация: 05.01.2010
Сообщений: 8
08.01.2010, 03:29     Чем же макрос define так плох? #1
После прочтения про директиву препроцессора define возник вопрос по поводу применения define, как функции:
C++
1
#define QQ (q) (q^q)
Можно же улучшить читаемость кода, используя вместо функций именно директиву define. Или у данного использования макроса есть подводные камки какие-то? Да и объем кода в разы сократиться, так как для define будет достаточно всего-навсего одной строчки.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.01.2010, 03:29     Чем же макрос define так плох?
Посмотрите здесь:

Объясните, в чем суть директив #ifndef/#define/#endif C++
C++ Чем оличается define от const
Чем плох C++
C++ В чем ошибка? что не так?
#define работает не так, как ожидается C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
24.10.2015, 17:21     Чем же макрос define так плох? #61
hoggy, вот тебе альтернативные ссылки с тем же кодом (раз уж у тебя эта не открывается): Раз, Два, Три.

Теперь про место для значения. Код:
C++
1
2
3
4
5
#include <cstdio>
 
int main() {
    printf( "%d\n", 42 );
}
Ассемблерный выхлоп:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
main:                                   # @main
    push    rbp
    mov rbp, rsp
    sub rsp, 16
    lea rdi, qword ptr [.L.str]
    mov esi, 42
    mov al, 0
    call    printf
    mov esi, 0
    mov dword ptr [rbp - 4], eax # 4-byte Spill
    mov eax, esi
    add rsp, 16
    pop rbp
    ret
 
.L.str:
    .asciz  "%d\n"
Убираем константу:
C++
1
2
3
4
5
#include <cstdio>
 
int main() {
    printf( "\n" );
}
Асм:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
main:                                   # @main
    push    rbp
    mov rbp, rsp
    sub rsp, 16
    lea rdi, qword ptr [.L.str]
    mov al, 0
    call    printf
    mov ecx, 0
    mov dword ptr [rbp - 4], eax # 4-byte Spill
    mov eax, ecx
    add rsp, 16
    pop rbp
    ret
 
.L.str:
    .asciz  "\n"
Как видишь, строки mov esi, 42 уже нет. Т.е. размер кода стал меньше.

Как вообще можно было предположить, что значение явно присутствующее в исходном файле, может выводиться на консоль и при этом НИГДЕ не храниться? Оно что из космоса прилетает?

Заметь, никаких адресов, о которых ты говорил, тут не используется, сугубо значение константы.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16843 / 5264 / 323
Регистрация: 30.03.2009
Сообщений: 14,159
Записей в блоге: 26
24.10.2015, 17:52     Чем же макрос define так плох? #62
Цитата Сообщение от hoggy Посмотреть сообщение
мой пример кода выше написан согласно стандатру.
а из этого следует, что любой копилятор обязан уметь делать inline подстановку
по месту использования фундаментальной константы
"Пример выше" это который?

Цитата Сообщение от hoggy Посмотреть сообщение
все топовые компиляторы умеют оптимизировать промежуточные значение
Из этого никак не следует, что const-переменная является константой

Добавлено через 29 секунд
Цитата Сообщение от Tulosba Посмотреть сообщение
Заметь, никаких адресов, о которых ты говорил, тут не используется, сугубо значение константы
Да тут же вопрос терминологии. Он веник называет пряником, а потому и сложно понять, чего он говорит
castaway
Эксперт С++
4848 / 2987 / 368
Регистрация: 10.11.2010
Сообщений: 11,028
Записей в блоге: 10
Завершенные тесты: 1
24.10.2015, 17:55     Чем же макрос define так плох? #63
Цитата Сообщение от Evg Посмотреть сообщение
const-переменная
const-переменная? Я не ослышался?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
24.10.2015, 18:16     Чем же макрос define так плох? #64
Цитата Сообщение от castaway Посмотреть сообщение
const-переменная? Я не ослышался?
const не дает гарантия константности. Так что да, это может быть переменная с квалификатором const
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
24.10.2015, 18:17     Чем же макрос define так плох? #65
Цитата Сообщение от castaway Посмотреть сообщение
const-переменная? Я не ослышался?
Ну, это нормально. Даже в Стандарте есть упоминание (3.5/3):
a variable that is explicitly declared const or constexpr and neither explicitly declared extern nor
previously declared to have external linkage;
Voivoid
 Аватар для Voivoid
580 / 256 / 12
Регистрация: 31.03.2013
Сообщений: 1,284
24.10.2015, 18:29     Чем же макрос define так плох? #66
* * lea rdi, qword ptr [.L.str]
* * mov esi, 42
* * mov al, 0
* * call* * printf
Вместо того, чтобы спорить об очевиндных вещах лучше расскажите почему аргументы для printf не ложатся на стек?
castaway
Эксперт С++
4848 / 2987 / 368
Регистрация: 10.11.2010
Сообщений: 11,028
Записей в блоге: 10
Завершенные тесты: 1
24.10.2015, 18:30     Чем же макрос define так плох? #67
Цитата Сообщение от Croessmah Посмотреть сообщение
const не дает гарантия константности.
Я что-то туплю под вечер после работы.. Это как?

Цитата Сообщение от Tulosba Посмотреть сообщение
Даже в Стандарте есть упоминание (3.5/3):
n4527? Что-то не найду у себя такого... Поиск фразу "variable that is explicitly declared const" тоже не находит.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
24.10.2015, 18:42     Чем же макрос define так плох? #68
Цитата Сообщение от castaway Посмотреть сообщение
Я что-то туплю под вечер после работы.. Это как?
я про константы времени компиляции. В теме же о них идет речь.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
24.10.2015, 18:51     Чем же макрос define так плох? #69
Цитата Сообщение от castaway Посмотреть сообщение
n4527?
Я в C++11 (ISO/IEC 14882 Third edition 2011-09-01) смотрел.
В драфте 3.5/(3.2):
a variable of non-volatile const-qualified type ...
Суть то же.

3/6:
A variable is introduced by the declaration of a reference other than a non-static data member or of an object. The variable’s name, if any, denotes the reference or object.
Добавлено через 2 минуты
Цитата Сообщение от Voivoid Посмотреть сообщение
почему аргументы для printf не ложатся на стек?
Поясни мысль.

Добавлено через 1 минуту
Цитата Сообщение от Croessmah Посмотреть сообщение
я про константы времени компиляции.
Не важно, компиляции или выполнения. Всё равно это в том числе и "переменная", хотя и принимающая только одно значение в момент инициализации.
castaway
Эксперт С++
4848 / 2987 / 368
Регистрация: 10.11.2010
Сообщений: 11,028
Записей в блоге: 10
Завершенные тесты: 1
24.10.2015, 19:01     Чем же макрос define так плох? #70
Цитата Сообщение от Croessmah Посмотреть сообщение
я про константы времени компиляции.
Цитата Сообщение от Tulosba Посмотреть сообщение
Не важно, компиляции или выполнения. Всё равно это в том числе и "переменная", хотя и принимающая только одно значение в момент инициализации.
Блин.. Я, конечно, могу представить о чём идёт речь, но я категорически не хочу укладывать у себя в уме понятие "константная переменная", ведь это противоположные сущности
LynXzp
1 / 0 / 0
Регистрация: 22.10.2015
Сообщений: 6
24.10.2015, 21:24     Чем же макрос define так плох? #71
Цитата Сообщение от hoggy Посмотреть сообщение
а из этого следует, что любой копилятор обязан уметь делать inline подстановку
Ура! Прояснилось
Цитата Сообщение от Tulosba Посмотреть сообщение
Как видишь, строки mov esi, 42 уже нет. Т.е. размер кода стал меньше...
Заметь, никаких адресов, о которых ты говорил, тут не используется, сугубо значение константы.
Так все отлично, она inline подставлена точно так же как и #define бы сделал.

Цитата Сообщение от Voivoid Посмотреть сообщение
Вместо того, чтобы спорить об очевиндных вещах лучше расскажите почему аргументы для printf не ложатся на стек?
Не знаю как в Win, думаю зависит от компилятора, например: http://habrahabr.ru/company/intel/blog/246913/ освободился регистр...
А в микроконтроллерах много регистров (32 например), и при этом мало памяти и производительности, поэтому компилятор (gcc) может по выбору оптимизации пихать в стек все регистры или не все (что делать с остальными регистрами придумать не сложно, но как на самом деле не скажу). Может esi в данном бинарнике такой регистр... выступает верхним значением стека. (ну это я так, на кофейной гуще, но выглядит правдоподобно для меня)
Croessmah
24.10.2015, 21:30
  #72

Не по теме:

Цитата Сообщение от castaway Посмотреть сообщение
не хочу укладывать у себя в уме понятие "константная переменная", ведь это противоположные сущности
тогда "переменная, объявленная с квалификатором const"

castaway
Эксперт С++
4848 / 2987 / 368
Регистрация: 10.11.2010
Сообщений: 11,028
Записей в блоге: 10
Завершенные тесты: 1
24.10.2015, 21:37     Чем же макрос define так плох? #73
Цитата Сообщение от Croessmah Посмотреть сообщение
тогда "переменная, объявленная с квалификатором const"
Ты меня опять путаешь. Можешь прояснить мне, дураку, в каких случаях квалификатор const не делает константу константной?
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,061
24.10.2015, 21:46     Чем же макрос define так плох? #74
Цитата Сообщение от ertyuo Посмотреть сообщение
#define QQ (q) (q^q)
а никто не заметил, что это 0 в случае q целочисленной
ошибка в случае вещественной, и хрен знает что в случае выражения
rikimaru2013
C++ Game Dev
 Аватар для rikimaru2013
2139 / 972 / 223
Регистрация: 30.11.2013
Сообщений: 3,241
24.10.2015, 21:46     Чем же макрос define так плох? #75
Цитата Сообщение от castaway Посмотреть сообщение
дураку
кажись там речь о том, что
C++
1
const int a = 10;
не означает, что в конце "a" будет точно иметь значение 10, спустя какое-то время. Есть хитрости изменить значение, но будет UB так как некоторые компиляторы могут закешировать значение константы (они так думают - ведь им так сказали) и вместо бегать по адрессу брать значение, вставлять его с своей таблици закэшированых значений констант.
LynXzp
1 / 0 / 0
Регистрация: 22.10.2015
Сообщений: 6
24.10.2015, 21:47     Чем же макрос define так плох? #76
Цитата Сообщение от castaway Посмотреть сообщение
но я категорически не хочу укладывать у себя в уме понятие "константная переменная"
Если я правильно понимаю то
const int a=5;

1. может при дальнейшем использовании подставится значением и это будет константная константа дальше некуда
(printf("%d",a) превращается компилятором в printf("%d",5))

2. а может создастся переменная в памяти и получится "константная переменная"
(например foo(&a); как говорили выше)

(Я всегда думал что создается константая переменная, почему-то даже в мыслях не было что она может стать inline. Просто константы в макросе это явно inline, а const int больше похоже на запрет модификации переменной.)
castaway
Эксперт С++
4848 / 2987 / 368
Регистрация: 10.11.2010
Сообщений: 11,028
Записей в блоге: 10
Завершенные тесты: 1
24.10.2015, 21:52     Чем же макрос define так плох? #77
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
не означает, что в конце "a" будет точно иметь значение 10.
Не понял ход твоей мысли...
Что значит "в конце"? Почему/по какой причине оно может измениться?
rikimaru2013
C++ Game Dev
 Аватар для rikimaru2013
2139 / 972 / 223
Регистрация: 30.11.2013
Сообщений: 3,241
24.10.2015, 22:01     Чем же макрос define так плох? #78
Цитата Сообщение от castaway Посмотреть сообщение
Почему/по какой причине оно может измениться?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
 
 
int main()
{
    const int a = 10;
    const int* ptr = &a;
    int* ptr2 = const_cast<int*>(ptr);
    *ptr2 = 14;                     // в Debug видно, что значение по адрессу &a изменилось на 14. 
    cout << a << endl;              // но выведет, к примеру в VS 2013, 10 - потому что закэшировал
    cout << *ptr << endl;
}
Код конечно не реалистичный так, как мало времени на придумывание было. Но факт, что рукожопов хватает и всё реально. И const не даёт 100% защиту, но без него - всеравно, что ездить на голой резине зимой с верой в бога!
LynXzp
1 / 0 / 0
Регистрация: 22.10.2015
Сообщений: 6
24.10.2015, 22:02     Чем же макрос define так плох? #79
Цитата Сообщение от castaway Посмотреть сообщение
Что значит "в конце"? Почему/по какой причине оно может измениться?
А если
foo(&a);
а foo - функция из подгруженной библиотеки черт его знает какого языка и компилятора. Вот возмет foo и запишет по адресу переменной a другое значение Если a не находится в защищенной области памяти и ОС это поддерживающей то пиши пропало.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.10.2015, 22:02     Чем же макрос define так плох?
Еще ссылки по теме:

C++ Палиндромы. Плох ли мой код?
Чем так отличается язык с++ от других языков программирования C++
C++ #define sqr(a) (a)*(a) - зачем так много скобок?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,061
24.10.2015, 22:02     Чем же макрос define так плох? #80
Цитата Сообщение от castaway Посмотреть сообщение
Почему/по какой причине оно может измениться?
ну например так
C++
1
2
3
const int a=5;
int b[1];
b[-1]=0;
но это грязный хак и UB в чистом виде
Yandex
Объявления
24.10.2015, 22:02     Чем же макрос define так плох?
Ответ Создать тему

Метки
#define
Опции темы

Текущее время: 02:05. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru