Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/86: Рейтинг темы: голосов - 86, средняя оценка - 4.78
0 / 0 / 0
Регистрация: 05.01.2010
Сообщений: 9
1

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

08.01.2010, 03:29. Показов 16676. Ответов 115

Author24 — интернет-сервис помощи студентам
После прочтения про директиву препроцессора define возник вопрос по поводу применения define, как функции:
C++
1
#define QQ (q) (q^q)
Можно же улучшить читаемость кода, используя вместо функций именно директиву define. Или у данного использования макроса есть подводные камки какие-то? Да и объем кода в разы сократиться, так как для define будет достаточно всего-навсего одной строчки.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.01.2010, 03:29
Ответы с готовыми решениями:

Чем так плох чипсет P31?
Здрасти! Скажите чем так плох этот чипсет?

чем плох mysql_query
Просматривал вакансию на пхп juniora наткнулся на такое требование "В коде нет и намека на...

Чем плох uCoz?
Добрый день! Хотел бы услышать объективные мнения специалистов, на тему "Почему юКоз нельзя...

Чем плох goto?
Вы хотели интересных тем? Так вот, я на днях думал, а почему goto так плох, и решил загуглить,...

115
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
24.10.2015, 17:21 61
Author24 — интернет-сервис помощи студентам
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
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
24.10.2015, 17:52 62
Цитата Сообщение от hoggy Посмотреть сообщение
мой пример кода выше написан согласно стандатру.
а из этого следует, что любой копилятор обязан уметь делать inline подстановку
по месту использования фундаментальной константы
"Пример выше" это который?

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

Добавлено через 29 секунд
Цитата Сообщение от Tulosba Посмотреть сообщение
Заметь, никаких адресов, о которых ты говорил, тут не используется, сугубо значение константы
Да тут же вопрос терминологии. Он веник называет пряником, а потому и сложно понять, чего он говорит
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
24.10.2015, 17:55 63
Цитата Сообщение от Evg Посмотреть сообщение
const-переменная
const-переменная? Я не ослышался?
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
24.10.2015, 18:16 64
Цитата Сообщение от castaway Посмотреть сообщение
const-переменная? Я не ослышался?
const не дает гарантия константности. Так что да, это может быть переменная с квалификатором const
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
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
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
24.10.2015, 18:29 66
* * lea rdi, qword ptr [.L.str]
* * mov esi, 42
* * mov al, 0
* * call* * printf
Вместо того, чтобы спорить об очевиндных вещах лучше расскажите почему аргументы для printf не ложатся на стек?
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
24.10.2015, 18:30 67
Цитата Сообщение от Croessmah Посмотреть сообщение
const не дает гарантия константности.
Я что-то туплю под вечер после работы.. Это как?

Цитата Сообщение от Tulosba Посмотреть сообщение
Даже в Стандарте есть упоминание (3.5/3):
n4527? Что-то не найду у себя такого... Поиск фразу "variable that is explicitly declared const" тоже не находит.
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
24.10.2015, 18:42 68
Цитата Сообщение от castaway Посмотреть сообщение
Я что-то туплю под вечер после работы.. Это как?
я про константы времени компиляции. В теме же о них идет речь.
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
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
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
24.10.2015, 19:01 70
Цитата Сообщение от Croessmah Посмотреть сообщение
я про константы времени компиляции.
Цитата Сообщение от Tulosba Посмотреть сообщение
Не важно, компиляции или выполнения. Всё равно это в том числе и "переменная", хотя и принимающая только одно значение в момент инициализации.
Блин.. Я, конечно, могу представить о чём идёт речь, но я категорически не хочу укладывать у себя в уме понятие "константная переменная", ведь это противоположные сущности
0
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
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
24.10.2015, 21:37 73
Цитата Сообщение от Croessmah Посмотреть сообщение
тогда "переменная, объявленная с квалификатором const"
Ты меня опять путаешь. Можешь прояснить мне, дураку, в каких случаях квалификатор const не делает константу константной?
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
24.10.2015, 21:46 74
Цитата Сообщение от ertyuo Посмотреть сообщение
#define QQ (q) (q^q)
а никто не заметил, что это 0 в случае q целочисленной
ошибка в случае вещественной, и хрен знает что в случае выражения
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
24.10.2015, 21:46 75
Цитата Сообщение от castaway Посмотреть сообщение
дураку
кажись там речь о том, что
C++
1
const int a = 10;
не означает, что в конце "a" будет точно иметь значение 10, спустя какое-то время. Есть хитрости изменить значение, но будет UB так как некоторые компиляторы могут закешировать значение константы (они так думают - ведь им так сказали) и вместо бегать по адрессу брать значение, вставлять его с своей таблици закэшированых значений констант.
1
1 / 0 / 0
Регистрация: 22.10.2015
Сообщений: 6
24.10.2015, 21:47 76
Цитата Сообщение от castaway Посмотреть сообщение
но я категорически не хочу укладывать у себя в уме понятие "константная переменная"
Если я правильно понимаю то
const int a=5;

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

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

(Я всегда думал что создается константая переменная, почему-то даже в мыслях не было что она может стать inline. Просто константы в макросе это явно inline, а const int больше похоже на запрет модификации переменной.)
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
24.10.2015, 21:52 77
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
не означает, что в конце "a" будет точно иметь значение 10.
Не понял ход твоей мысли...
Что значит "в конце"? Почему/по какой причине оно может измениться?
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
24.10.2015, 22:01 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% защиту, но без него - всеравно, что ездить на голой резине зимой с верой в бога!
1
1 / 0 / 0
Регистрация: 22.10.2015
Сообщений: 6
24.10.2015, 22:02 79
Цитата Сообщение от castaway Посмотреть сообщение
Что значит "в конце"? Почему/по какой причине оно может измениться?
А если
foo(&a);
а foo - функция из подгруженной библиотеки черт его знает какого языка и компилятора. Вот возмет foo и запишет по адресу переменной a другое значение Если a не находится в защищенной области памяти и ОС это поддерживающей то пиши пропало.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
24.10.2015, 22:02 80
Цитата Сообщение от castaway Посмотреть сообщение
Почему/по какой причине оно может измениться?
ну например так
C++
1
2
3
const int a=5;
int b[1];
b[-1]=0;
но это грязный хак и UB в чистом виде
1
24.10.2015, 22:02
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.10.2015, 22:02
Помогаю со студенческими работами здесь

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

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

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

Чем плох ProBuilder (Unity3D)?
Мне советовали не использовать ProBuilder, а моделить в какой-нибудь проге - текстурить и потом...


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru