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

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

Войти
Регистрация
Восстановить пароль
 
 
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
#1

Необходимо разобораться с предопределёнными макросами (компилятор g++) - C++

10.02.2014, 17:23. Просмотров 916. Ответов 16
Метки нет (Все метки)

Друзья! Этой темой начинается (надеюсь, ей и закончится) цикл вопросов про предопределённые макросы. Те, которые мы определяем сами (или другие разработчики) , с ними можно разобраться, статью все знают, где читать. Те, которые определены компилятором- по ним вообще мало инфы.

+++++++++++++++++++++++++++++++++++++++++++++

Итак, предопределённый макрос __FUNCTION__; читаем у Гриффитса:
Строка в кавычках, содержащая имя текущей функции.
Скропаем исходник с этим макросом, дабы определить- он вообще ЖИВОЙ? (Не могу подобрать другого слова, а термин "предопределён" тут не подходит, позже поймёте почему)
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <windows.h>
#include <stdio.h>
 
int main() {
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    printf (__FUNCTION__);
    
    getchar ();
    return 0;
}
Командуем:
Bash
1
2
g++ -o main.exe main.cpp
main.exe
(думаю, если будете компилить с опциями по умолчанию в той же Dev-C++, большой ошибки не будет)
Наблюдаем:
Bash
1
main
ОК, вывод: макрос __FUNCTION__ вполне себе жив. А теперь попробуем ГРАМОТНО найти предопределённые макросы, которые предопределяются компилятором при компиляции main.cpp; __FUNCTION__ среди них не будет. Читаем у Гриффитса:
Можете использовать опцию препроцессора -dМ, чтобы увидеть весь их список. Подаваемая для этоrо команда должна выrлядеть примерно так:
срр E -dМ myprog.c | sort | more
Список, выводимый по этой команде, содержит директивы #define для каждоro макроса, определённоrо препроцессором после обработки указанноrо исходноrо файла и всех включаемых им заголовочных файлов.
Командуем:
Bash
1
срр -E -dМ main.cpp> rez.txt
, открываем файл rez.txt, там будет куча макросов всяких, но __FUNCTION__ среди них не будет, почему?

++++++++++++++++++++++++++++++++++++++++++++

То есть если бы __FUNCTION__ ВООБЩЕ не был живым, было бы как-то понятнее. Можно было бы предположить, что мой компилятор его не предопределяет- а не обязан потому что по стандарту. (к сожалению, это так, пункт 16.8 стандарта.) Но он в одном случае предопределён (при использовании), а в другом нет (при выводе предопределённых макросов). Почему так? Спасибо, кто откликнется, g++ 4.6.2
1
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.02.2014, 17:23
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Необходимо разобораться с предопределёнными макросами (компилятор g++) (C++):

Конструкторы ofstream и стандарт C++11 и компилятор gcc необходимо разобраться - C++
Друзья! Условимся, что компилятор g++ поддерживает этот стандарт, ибо ошибок, говорящих об обратном не замечено вроде. //main.cpp ...

Компилятор (Visual C++ 6.0) в плохой совместимости с Windows 7. Посоветуйте другой компилятор - C++
Здравствуйте! Я недавно начал заниматься С++, но мой компилятор (Visual C++ 6.0) в плохой совместимости с Windows 7 Посоветуйте какой...

Не работает код с макросами - C++
Совсем новичок. Необходимо вычислить дискриминант. Есть код, но проблема в том, что я не понимаю почему он работает неправильно. Суть...

зачем функции оборачивают макросами? - C++
Часто встречаю в библиотеке opencv фукции обернутые макросами, для чего это применяют Например: H1.h ... #define MACRO H2.h...

Алгоритмы из <algorithm> являются макросами или всё же функциями? - C++
Интересно насколько эффективно использовать тривиальные алгоритмы из библиотеки &lt;algorithm&gt;? Кто-нибудь использует их вообще? Сильно ли...

Отредактируйте проги чтобы было макросами, препроцесорные функцыии!С++,макросы - C++
Неразобралоса толком в них, зарание спасибо! Макросы - это препроцессорные &quot;функции&quot; , т.е. лексемы, созданные с помощью директивы...

16
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
12.02.2014, 10:43  [ТС] #2
Ну что, ребята, какие будут мысли по этому поводу?
0
NoMasters
Псевдослучайный
1765 / 1107 / 74
Регистрация: 13.09.2011
Сообщений: 3,149
12.02.2014, 11:26 #3
Очевидно, что невозможно всегда иметь одно и тоже значение для всего файла, поэтому и предоставить что-то вразумительное на вывод этой команды затруднительно.
Более того, конкретно __FUNCTION__ не может обрабатываться препроцессором, ибо он вообще не знает имя текущей функции, то есть макросом в общем-то и не является.
Между тем, __FUNCTION__ — штука нестандартная, зато с С99 и С++11 есть __func__.
2
programina
1916 / 601 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
12.02.2014, 11:38 #4
Прикольно! А какие еще есть встроенные макроопределения?
0
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
12.02.2014, 11:53 #5
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от kravam Посмотреть сообщение
Ну что, ребята, какие будут мысли по этому поводу?
Как говорил профессор Преображенский: "не читайте до обеда советских газет". Это я к тому, что ответы на вопросы по поводу GCC лучше искать не в книжках, а непосредственно в мануале по GCC.

Ответ прост, __FUNCTION__ - это не макрос. Ответ тут.
C99 introduces __func__, and GCC has provided __FUNCTION__ for a long time. Both of these are strings containing the name of the current function (there are slight semantic differences; see the GCC manual). Neither of them is a macro; the preprocessor does not know the name of the current function. They tend to be useful in conjunction with __FILE__ and __LINE__, though.
2
programina
1916 / 601 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
12.02.2014, 12:03 #6
Почему то не работают...
Bash
__STDC_VERSION__
__OBJC__
__ASSEMBLER__
0
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
12.02.2014, 12:32 #7
Цитата Сообщение от programina Посмотреть сообщение
Почему то не работают...
Bash
__STDC_VERSION__
__OBJC__
__ASSEMBLER__
Там в писании все указано В С++ работать не будет.
1
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
15.02.2014, 22:41  [ТС] #8
Цитата Сообщение от DrOffset Посмотреть сообщение
Ответ прост, __FUNCTION__ - это не макрос
А что это? Какая-то незадокументированная конструкция, получается.

Добавлено через 6 минут
Получается, он наполовину макрос, наполовину нет. Тут он макрос:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <windows.h>
#include <stdio.h>
 
int main() {
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    printf (__FUNCTION__);
    
    getchar ();
    return 0;
}
А тут нет:
Bash
1
срр -E -dМ main.cpp> rez.txt
как же так, ребята?
0
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
15.02.2014, 22:45 #9
Цитата Сообщение от kravam Посмотреть сообщение
А что это? Какая-то незадокументированная конструкция, получается.
Я же дал ссылку на документацию GCC где об этом прямым текстом написано. Даже цитату сюда выписал и жирным подсветил
Конструкция документирована. Просто она не макрос - это предопределенный идентификатор.
Что-то вроде:
C++
1
static const char __FUNCTION__[] = "function-name";
для каждой функции.
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
16.02.2014, 00:25  [ТС] #10
Не думайте обо мне так плохо. Просто я плохо знаю английский язык. Кроме того, я не нашёл там, что она- предопределённый идентификатор. Что она не макрос, я прочёл. Что она содержит имя вызываемой функции я знал. Осталось узнать- как это называется, дабы обратиться к соответсвующему разделу "Predefined identifikator" (в стандарте или где) и всё про них узнать, всю их суть. А чёткого названия как-раз таки и не дано.

Добавлено через 13 минут
Я вот сейчас увидел, что __func__уделено-таки некоторое внимание в стандарте:
The function-local predefined variable __func__ is defined as if a definition of the form
static const char __func__[] = "function-name ";

had been provided, where function-name is an implementation-defined string. It is unspecified whether such
a variable has an address distinct from that of any other object in the program.102
Наверное, надо плясать от того, что она "an implementation-defined string". Сейчас попытаюсь определить, что это значит.
0
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
16.02.2014, 14:43 #11
Цитата Сообщение от kravam Посмотреть сообщение
Кроме того, я не нашёл там, что она- предопределённый идентификатор. Что она не макрос, я прочёл. Что она содержит имя вызываемой функции я знал. Осталось узнать- как это называется, дабы обратиться к соответсвующему разделу
В стандарте С++ этого не найти. Потому что это фича компилятора. Следовательно, первый источник мануал по компилятору.

В мануале GCC действительно не написано, что это именно идентификатор. Но это логически следует из описания. Однако я могу дать ссылку на другие источники где это четко обозначено, например вот.

Либо, можно обратиться к стандарту С, там есть __func__ который семантически соответствует __FUNCTION__.
6.4.2.2
Predefined identifiers
Semantics
1 The identifier _ _func_ _ shall be implicitly declared by the translator as if,
immediately following the opening brace of each function definition, the declaration
static const char _ _func_ _[]="function-name";
appeared, where function-name is the name of the lexically-enclosing function.

2 This name is encoded as if the implicit declaration had been written in the source
character set and then translated into the execution character set as indicated in translation
phase 5.
Добавлено через 14 часов 13 минут
Цитата Сообщение от kravam Посмотреть сообщение
Наверное, надо плясать от того, что она "an implementation-defined string". Сейчас попытаюсь определить, что это значит.
Это в старом стандарте. В последних двух (С99 и С11) это называется "predefined identifier".
Значит это то, что в случае обращения к такому идентификатору внутри функции, компилятор автоматически генерирует константу такого вида
static const char _ _func_ _[]="function-name"
и заносит туда строку с именем этой функции. Об этом написано и в вашей цитате. Ну и см. мой предыдущий пост с цитатой из более нового стандарта.

Вроде теперь все на своих местах, нет?
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
17.02.2014, 01:39  [ТС] #12
Цитата Сообщение от DrOffset Посмотреть сообщение
Вроде теперь все на своих местах, нет?
Я буду разбираться, а теперь,то, что на поверхности. Уточнение о терминах:

Цитата Сообщение от DrOffset Посмотреть сообщение
В последних двух (С99 и С11) это называется "predefined identifier".
Если мы говорим о стандарте C++, то с точностью до наоборот. Вот последний стандарт. Я заколебался пыль глотать искать в нём "predefined identifier", а "implementation-defined" как раз таки- есть сплошь и рядом.
0
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
17.02.2014, 18:49 #13
Цитата Сообщение от kravam Посмотреть сообщение
Если мы говорим о стандарте C++, то с точностью до наоборот. Вот последний стандарт. Я заколебался пыль глотать искать в нём "predefined identifier", а "implementation-defined" как раз таки- есть сплошь и рядом.
Какой смысл искать просто слова "predefined identifier", а "implementation-defined"? - это же не словарь какой-то. Эти слова могут употребляться в разных смыслах, не обязательно в том, который мы подразумеваем в данный момент.

Лучше открыть новый стандарт и заняться в нем поиском не всего подряд, а значимых вещей. Например вот:
8.4.1/8
The function-local predefined variable __func__ is defined as if a definition of the form
static const char __func__[] = "function-name ";
had been provided, where function-name is an implementation-defined string. It is unspecified whether such
a variable has an address distinct from that of any other object in the program.

[Example:
struct S {
S() : s(__func__) { } // OK
const char *s;
};
void f(const char * s = __func__); // error: __func__ is undeclared
Как видно из примера, стандарт полностью подтверждает мои слова. __func__ - это локальный для функции константный идентификатор, который содержит строку с именем функции. predefined variable в данном случае полный синоним predefined identifier. А вот строка implementation-defined string, уже означает, что содержимое строки может быть различно в зависимости от реализации (компилятора).
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,489
17.02.2014, 18:54  [ТС] #14
Цитата Сообщение от DrOffset Посмотреть сообщение
Лучше открыть новый стандарт и заняться в нем поиском не всего подряд, а значимых вещей. Например вот:
Да, но, разве не эту же цитату я привёл вам из этого же источника некоторое время назад?
Щас я буду всё это систематизировать.
0
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
17.02.2014, 18:59 #15
Цитата Сообщение от kravam Посмотреть сообщение
Да, но, разве не эту же цитату я привёл вам из этого же источника некоторое время назад?
Щас я буду всё это систематизировать.
Прошу прощения. Я думал, что мы разговариваем в контексте стандартов С. Так как до недавнего времени в С++ стандарте не было никаких инструментов наподобие __func__ (были только расширения компиляторов, которые описывались в мануалах к компилятору, но не в стандарте). Поэтому подумал, что вы ссылаетесь на С стандарт Но в целом это ничего не меняет. Смысл фразы все равно один. И я его уже озвучил.
0
17.02.2014, 18:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.02.2014, 18:59
Привет! Вот еще темы с ответами:

Помогите разобораться! Срочно! - Oracle
Всем привет! хотелось бы уточнить, если на одном компе стоит сервер Оракла, на втором компе - Web сервер(IIS).... 1) то надо на...

Ошибка: Необходимо в настройках комплекта задать компилятор для сборки - C++ Qt
Возникает ошибка: Необходимо в настройках комплекта задать компилятор для сборки Что делать? Опишите пошагово для идиота(я только...

Правда ли, что для написания программ "для продажи" необходимо иметь лицензионный компилятор? - Разработка ПО
Выходит, что чтобы написать свою прогу и продавать её, я должен купить лицензию. Ну, если по совести - это правильно. А как на...

Работа с макросами - VBA
I) Access 1. Создать макрос «Общий», который открывает поочередно таблицу, запросы, формы, схему данных в полном развернутом состоянии...


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

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

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