Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 52, средняя оценка - 4.90
ertyuo
0 / 0 / 0
Регистрация: 05.01.2010
Сообщений: 9
#1

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

08.01.2010, 03:29. Просмотров 7596. Ответов 115

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

Чем плох make? - C++
Дали написать реферат по make файлам и соответственно указать его минусы, а значит сравнить его с такими утилитами как CMake, но для меня...

Чем плох std::map? - C++
std::map ?

Чем плох void main? - C++
Встретил мнение, что void main() - не канон и даже плохо. Но статья древняя, 1996 года, и даже автор открестился, сказав, что для новых...

Чем плох управляемый С++? - C++
Я дико извиняюсь за подобную тему... но дело в том, что мне сегодня задали этот вопрос и, собственно, я не смог на него ответить. Сам я...

Перевести макрос define в функцию - C++
Доброго времени суток. Я тут на днях набросал вот такие макросы для удобства: #define BinSave(Value, Root)\ //Переменная, путь к...

Чем оличается define от const - C++
define A 5; и const a = 5; В первом случае идет замена в предпроцессоре... а во втором? и еще слышал что define оч редко стал...

115
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
24.10.2015, 17:21 #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 уже нет. Т.е. размер кода стал меньше.

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

Заметь, никаких адресов, о которых ты говорил, тут не используется, сугубо значение константы.
1
Evg
Эксперт CАвтор FAQ
18372 / 6419 / 441
Регистрация: 30.03.2009
Сообщений: 17,807
Записей в блоге: 28
24.10.2015, 17:52 #62
Цитата Сообщение от hoggy Посмотреть сообщение
мой пример кода выше написан согласно стандатру.
а из этого следует, что любой копилятор обязан уметь делать inline подстановку
по месту использования фундаментальной константы
"Пример выше" это который?

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

Добавлено через 29 секунд
Цитата Сообщение от Tulosba Посмотреть сообщение
Заметь, никаких адресов, о которых ты говорил, тут не используется, сугубо значение константы
Да тут же вопрос терминологии. Он веник называет пряником, а потому и сложно понять, чего он говорит
0
castaway
Эксперт С++
4916 / 3024 / 370
Регистрация: 10.11.2010
Сообщений: 11,081
Записей в блоге: 10
Завершенные тесты: 1
24.10.2015, 17:55 #63
Цитата Сообщение от Evg Посмотреть сообщение
const-переменная
const-переменная? Я не ослышался?
0
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
24.10.2015, 18:16 #64
Цитата Сообщение от castaway Посмотреть сообщение
const-переменная? Я не ослышался?
const не дает гарантия константности. Так что да, это может быть переменная с квалификатором const
1
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
24.10.2015, 18:17 #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;
1
Voivoid
675 / 278 / 12
Регистрация: 31.03.2013
Сообщений: 1,339
24.10.2015, 18:29 #66
* * lea rdi, qword ptr [.L.str]
* * mov esi, 42
* * mov al, 0
* * call* * printf
Вместо того, чтобы спорить об очевиндных вещах лучше расскажите почему аргументы для printf не ложатся на стек?
0
castaway
Эксперт С++
4916 / 3024 / 370
Регистрация: 10.11.2010
Сообщений: 11,081
Записей в блоге: 10
Завершенные тесты: 1
24.10.2015, 18:30 #67
Цитата Сообщение от Croessmah Посмотреть сообщение
const не дает гарантия константности.
Я что-то туплю под вечер после работы.. Это как?

Цитата Сообщение от Tulosba Посмотреть сообщение
Даже в Стандарте есть упоминание (3.5/3):
n4527? Что-то не найду у себя такого... Поиск фразу "variable that is explicitly declared const" тоже не находит.
0
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
24.10.2015, 18:42 #68
Цитата Сообщение от castaway Посмотреть сообщение
Я что-то туплю под вечер после работы.. Это как?
я про константы времени компиляции. В теме же о них идет речь.
1
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
24.10.2015, 18:51 #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 Посмотреть сообщение
я про константы времени компиляции.
Не важно, компиляции или выполнения. Всё равно это в том числе и "переменная", хотя и принимающая только одно значение в момент инициализации.
1
castaway
Эксперт С++
4916 / 3024 / 370
Регистрация: 10.11.2010
Сообщений: 11,081
Записей в блоге: 10
Завершенные тесты: 1
24.10.2015, 19:01 #70
Цитата Сообщение от Croessmah Посмотреть сообщение
я про константы времени компиляции.
Цитата Сообщение от Tulosba Посмотреть сообщение
Не важно, компиляции или выполнения. Всё равно это в том числе и "переменная", хотя и принимающая только одно значение в момент инициализации.
Блин.. Я, конечно, могу представить о чём идёт речь, но я категорически не хочу укладывать у себя в уме понятие "константная переменная", ведь это противоположные сущности
0
LynXzp
1 / 0 / 0
Регистрация: 22.10.2015
Сообщений: 6
24.10.2015, 21:24 #71
Цитата Сообщение от hoggy Посмотреть сообщение
а из этого следует, что любой копилятор обязан уметь делать inline подстановку
Ура! Прояснилось
Цитата Сообщение от Tulosba Посмотреть сообщение
Как видишь, строки mov esi, 42 уже нет. Т.е. размер кода стал меньше...
Заметь, никаких адресов, о которых ты говорил, тут не используется, сугубо значение константы.
Так все отлично, она inline подставлена точно так же как и #define бы сделал.

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

Не по теме:

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

0
castaway
Эксперт С++
4916 / 3024 / 370
Регистрация: 10.11.2010
Сообщений: 11,081
Записей в блоге: 10
Завершенные тесты: 1
24.10.2015, 21:37 #73
Цитата Сообщение от Croessmah Посмотреть сообщение
тогда "переменная, объявленная с квалификатором const"
Ты меня опять путаешь. Можешь прояснить мне, дураку, в каких случаях квалификатор const не делает константу константной?
0
ValeryS
Модератор
6729 / 5138 / 484
Регистрация: 14.02.2011
Сообщений: 17,240
24.10.2015, 21:46 #74
Цитата Сообщение от ertyuo Посмотреть сообщение
#define QQ (q) (q^q)
а никто не заметил, что это 0 в случае q целочисленной
ошибка в случае вещественной, и хрен знает что в случае выражения
0
rikimaru2013
C++ Game Dev
2440 / 1133 / 240
Регистрация: 30.11.2013
Сообщений: 3,690
24.10.2015, 21:46 #75
Цитата Сообщение от castaway Посмотреть сообщение
дураку
кажись там речь о том, что
C++
1
const int a = 10;
не означает, что в конце "a" будет точно иметь значение 10, спустя какое-то время. Есть хитрости изменить значение, но будет UB так как некоторые компиляторы могут закешировать значение константы (они так думают - ведь им так сказали) и вместо бегать по адрессу брать значение, вставлять его с своей таблици закэшированых значений констант.
1
24.10.2015, 21:46
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.10.2015, 21:46
Привет! Вот еще темы с ответами:

#define работает не так, как ожидается - C++
Здравствуйте. Подскажите, пожалуйста, почему в таком случае некорректно использовать #define: switch (kind) { case 1: ...

#define sqr(a) (a)*(a) - зачем так много скобок? - C++
#define sqr(a) ((a)*(a)) такие вопросы: 1) Зачем ((a)*(a)) так много скобок? (если можно,объяснить доступным языком) 2) почему,...

Объясните, в чем суть директив #ifndef/#define/#endif - C++
Не понял в чем суть директив: #ifndef .. #define.. #endifОбъясните пожалуйста..это как - то связано с хедерами, но вот как ??

Что это за макрос? И с чем его едят? - C++
Есть две строки. С первой вроде разобрался, поправьте если не совсем. Из книги Лафоре ООП (реализация консольной графики). #ifndef...


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

Или воспользуйтесь поиском по форуму:
75
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.