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

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

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

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

10.02.2014, 17:23. Просмотров 815. Ответов 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)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.02.2014, 17:23     Необходимо разобораться с предопределёнными макросами (компилятор g++)
Посмотрите здесь:
Конструкторы ofstream и стандарт C++11 и компилятор gcc необходимо разобраться C++
C++ Не работает код с макросами
C++ зачем функции оборачивают макросами?
C++ Алгоритмы из <algorithm> являются макросами или всё же функциями?
Отредактируйте проги чтобы было макросами, препроцесорные функцыии!С++,макросы C++
компилятор c++ C++
C++ Компилятор С++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,439
12.02.2014, 10:43  [ТС]     Необходимо разобораться с предопределёнными макросами (компилятор g++) #2
Ну что, ребята, какие будут мысли по этому поводу?
NoMasters
Псевдослучайный
1747 / 1090 / 71
Регистрация: 13.09.2011
Сообщений: 3,121
12.02.2014, 11:26     Необходимо разобораться с предопределёнными макросами (компилятор g++) #3
Очевидно, что невозможно всегда иметь одно и тоже значение для всего файла, поэтому и предоставить что-то вразумительное на вывод этой команды затруднительно.
Более того, конкретно __FUNCTION__ не может обрабатываться препроцессором, ибо он вообще не знает имя текущей функции, то есть макросом в общем-то и не является.
Между тем, __FUNCTION__ — штука нестандартная, зато с С99 и С++11 есть __func__.
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
12.02.2014, 11:38     Необходимо разобораться с предопределёнными макросами (компилятор g++) #4
Прикольно! А какие еще есть встроенные макроопределения?
DrOffset
7060 / 4201 / 949
Регистрация: 30.01.2014
Сообщений: 6,968
12.02.2014, 11:53     Необходимо разобораться с предопределёнными макросами (компилятор g++) #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.
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
12.02.2014, 12:03     Необходимо разобораться с предопределёнными макросами (компилятор g++) #6
Почему то не работают...
Bash
__STDC_VERSION__
__OBJC__
__ASSEMBLER__
DrOffset
7060 / 4201 / 949
Регистрация: 30.01.2014
Сообщений: 6,968
12.02.2014, 12:32     Необходимо разобораться с предопределёнными макросами (компилятор g++) #7
Цитата Сообщение от programina Посмотреть сообщение
Почему то не работают...
Bash
__STDC_VERSION__
__OBJC__
__ASSEMBLER__
Там в писании все указано В С++ работать не будет.
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,439
15.02.2014, 22:41  [ТС]     Необходимо разобораться с предопределёнными макросами (компилятор g++) #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
как же так, ребята?
DrOffset
7060 / 4201 / 949
Регистрация: 30.01.2014
Сообщений: 6,968
15.02.2014, 22:45     Необходимо разобораться с предопределёнными макросами (компилятор g++) #9
Цитата Сообщение от kravam Посмотреть сообщение
А что это? Какая-то незадокументированная конструкция, получается.
Я же дал ссылку на документацию GCC где об этом прямым текстом написано. Даже цитату сюда выписал и жирным подсветил
Конструкция документирована. Просто она не макрос - это предопределенный идентификатор.
Что-то вроде:
C++
1
static const char __FUNCTION__[] = "function-name";
для каждой функции.
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,439
16.02.2014, 00:25  [ТС]     Необходимо разобораться с предопределёнными макросами (компилятор g++) #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". Сейчас попытаюсь определить, что это значит.
DrOffset
7060 / 4201 / 949
Регистрация: 30.01.2014
Сообщений: 6,968
16.02.2014, 14:43     Необходимо разобораться с предопределёнными макросами (компилятор g++) #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"
и заносит туда строку с именем этой функции. Об этом написано и в вашей цитате. Ну и см. мой предыдущий пост с цитатой из более нового стандарта.

Вроде теперь все на своих местах, нет?
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,439
17.02.2014, 01:39  [ТС]     Необходимо разобораться с предопределёнными макросами (компилятор g++) #12
Цитата Сообщение от DrOffset Посмотреть сообщение
Вроде теперь все на своих местах, нет?
Я буду разбираться, а теперь,то, что на поверхности. Уточнение о терминах:

Цитата Сообщение от DrOffset Посмотреть сообщение
В последних двух (С99 и С11) это называется "predefined identifier".
Если мы говорим о стандарте C++, то с точностью до наоборот. Вот последний стандарт. Я заколебался пыль глотать искать в нём "predefined identifier", а "implementation-defined" как раз таки- есть сплошь и рядом.
DrOffset
7060 / 4201 / 949
Регистрация: 30.01.2014
Сообщений: 6,968
17.02.2014, 18:49     Необходимо разобораться с предопределёнными макросами (компилятор g++) #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, уже означает, что содержимое строки может быть различно в зависимости от реализации (компилятора).
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,439
17.02.2014, 18:54  [ТС]     Необходимо разобораться с предопределёнными макросами (компилятор g++) #14
Цитата Сообщение от DrOffset Посмотреть сообщение
Лучше открыть новый стандарт и заняться в нем поиском не всего подряд, а значимых вещей. Например вот:
Да, но, разве не эту же цитату я привёл вам из этого же источника некоторое время назад?
Щас я буду всё это систематизировать.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.02.2014, 18:59     Необходимо разобораться с предопределёнными макросами (компилятор g++)
Еще ссылки по теме:
Компилятор C++
компилятор с++ C++
C++ Компилятор C не C++
Компилятор C++
Компилятор C++ C++

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

Или воспользуйтесь поиском по форуму:
DrOffset
7060 / 4201 / 949
Регистрация: 30.01.2014
Сообщений: 6,968
17.02.2014, 18:59     Необходимо разобораться с предопределёнными макросами (компилятор g++) #15
Цитата Сообщение от kravam Посмотреть сообщение
Да, но, разве не эту же цитату я привёл вам из этого же источника некоторое время назад?
Щас я буду всё это систематизировать.
Прошу прощения. Я думал, что мы разговариваем в контексте стандартов С. Так как до недавнего времени в С++ стандарте не было никаких инструментов наподобие __func__ (были только расширения компиляторов, которые описывались в мануалах к компилятору, но не в стандарте). Поэтому подумал, что вы ссылаетесь на С стандарт Но в целом это ничего не меняет. Смысл фразы все равно один. И я его уже озвучил.
Yandex
Объявления
17.02.2014, 18:59     Необходимо разобораться с предопределёнными макросами (компилятор g++)
Ответ Создать тему
Опции темы

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