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

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

Восстановить пароль Регистрация
 
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
10.02.2014, 17:23     Необходимо разобораться с предопределёнными макросами (компилятор g++) #1
Друзья! Этой темой начинается (надеюсь, ей и закончится) цикл вопросов про предопределённые макросы. Те, которые мы определяем сами (или другие разработчики) , с ними можно разобраться, статью все знают, где читать. Те, которые определены компилятором- по ним вообще мало инфы.

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

Итак, предопределённый макрос __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++)
Посмотрите здесь:

Компилятор C++
Отредактируйте проги чтобы было макросами, препроцесорные функцыии!С++,макросы C++
C++ Алгоритмы из <algorithm> являются макросами или всё же функциями?
Компилятор C++
C++ компилятор
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
12.02.2014, 10:43  [ТС]     Необходимо разобораться с предопределёнными макросами (компилятор g++) #2
Ну что, ребята, какие будут мысли по этому поводу?
NoMasters
Псевдослучайный
1737 / 1080 / 69
Регистрация: 13.09.2011
Сообщений: 3,093
12.02.2014, 11:26     Необходимо разобораться с предопределёнными макросами (компилятор g++) #3
Очевидно, что невозможно всегда иметь одно и тоже значение для всего файла, поэтому и предоставить что-то вразумительное на вывод этой команды затруднительно.
Более того, конкретно __FUNCTION__ не может обрабатываться препроцессором, ибо он вообще не знает имя текущей функции, то есть макросом в общем-то и не является.
Между тем, __FUNCTION__ — штука нестандартная, зато с С99 и С++11 есть __func__.
programina
 Аватар для programina
1912 / 597 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
12.02.2014, 11:38     Необходимо разобораться с предопределёнными макросами (компилятор g++) #4
Прикольно! А какие еще есть встроенные макроопределения?
DrOffset
6425 / 3799 / 880
Регистрация: 30.01.2014
Сообщений: 6,592
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
 Аватар для programina
1912 / 597 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
12.02.2014, 12:03     Необходимо разобораться с предопределёнными макросами (компилятор g++) #6
Почему то не работают...
Bash
__STDC_VERSION__
__OBJC__
__ASSEMBLER__
DrOffset
6425 / 3799 / 880
Регистрация: 30.01.2014
Сообщений: 6,592
12.02.2014, 12:32     Необходимо разобораться с предопределёнными макросами (компилятор g++) #7
Цитата Сообщение от programina Посмотреть сообщение
Почему то не работают...
Bash
__STDC_VERSION__
__OBJC__
__ASSEMBLER__
Там в писании все указано В С++ работать не будет.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
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
6425 / 3799 / 880
Регистрация: 30.01.2014
Сообщений: 6,592
15.02.2014, 22:45     Необходимо разобораться с предопределёнными макросами (компилятор g++) #9
Цитата Сообщение от kravam Посмотреть сообщение
А что это? Какая-то незадокументированная конструкция, получается.
Я же дал ссылку на документацию GCC где об этом прямым текстом написано. Даже цитату сюда выписал и жирным подсветил
Конструкция документирована. Просто она не макрос - это предопределенный идентификатор.
Что-то вроде:
C++
1
static const char __FUNCTION__[] = "function-name";
для каждой функции.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
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
6425 / 3799 / 880
Регистрация: 30.01.2014
Сообщений: 6,592
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
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
17.02.2014, 01:39  [ТС]     Необходимо разобораться с предопределёнными макросами (компилятор g++) #12
Цитата Сообщение от DrOffset Посмотреть сообщение
Вроде теперь все на своих местах, нет?
Я буду разбираться, а теперь,то, что на поверхности. Уточнение о терминах:

Цитата Сообщение от DrOffset Посмотреть сообщение
В последних двух (С99 и С11) это называется "predefined identifier".
Если мы говорим о стандарте C++, то с точностью до наоборот. Вот последний стандарт. Я заколебался пыль глотать искать в нём "predefined identifier", а "implementation-defined" как раз таки- есть сплошь и рядом.
DrOffset
6425 / 3799 / 880
Регистрация: 30.01.2014
Сообщений: 6,592
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
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
17.02.2014, 18:54  [ТС]     Необходимо разобораться с предопределёнными макросами (компилятор g++) #14
Цитата Сообщение от DrOffset Посмотреть сообщение
Лучше открыть новый стандарт и заняться в нем поиском не всего подряд, а значимых вещей. Например вот:
Да, но, разве не эту же цитату я привёл вам из этого же источника некоторое время назад?
Щас я буду всё это систематизировать.
DrOffset
6425 / 3799 / 880
Регистрация: 30.01.2014
Сообщений: 6,592
17.02.2014, 18:59     Необходимо разобораться с предопределёнными макросами (компилятор g++) #15
Цитата Сообщение от kravam Посмотреть сообщение
Да, но, разве не эту же цитату я привёл вам из этого же источника некоторое время назад?
Щас я буду всё это систематизировать.
Прошу прощения. Я думал, что мы разговариваем в контексте стандартов С. Так как до недавнего времени в С++ стандарте не было никаких инструментов наподобие __func__ (были только расширения компиляторов, которые описывались в мануалах к компилятору, но не в стандарте). Поэтому подумал, что вы ссылаетесь на С стандарт Но в целом это ничего не меняет. Смысл фразы все равно один. И я его уже озвучил.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
18.02.2014, 20:32  [ТС]     Необходимо разобораться с предопределёнными макросами (компилятор g++) #16
Ну, что же, картина прояснилась более или менее. Оказывается, по стандарту C++, существуют две сущности очень друг на друга похожие- предопределённые макросы и штука, называемая implementation-defined. И те и другие можно прочесть в стандарте. Использовать можно по разному, либо для вывода полезной информации, а в случае __cplusplus- так тот вообще определяет, как компилятором трактуется исходник- как Cи или как C++.

Ну, пожалуй, дальше в своих выводах я не пойду. Всё остальное надо читать в мануалах к собственному компилятору, а они в комплекте не шли. Теперь если буду менять компилятор, надо искать с мануалами- если такие в природе есть. Я-то думал, что Гриффитса и стандарта за глаза хватит, а оно вон как вышло.

А к линуксному пояснению по GCC, обращаться я пока не буду- там ведь тоже некий стандарт, а как мой mingw себя ведёт на самом деле- поди знай.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.02.2014, 20:53     Необходимо разобораться с предопределёнными макросами (компилятор g++)
Еще ссылки по теме:

C++ Компилятор
Конструкторы ofstream и стандарт C++11 и компилятор gcc необходимо разобраться C++
C++ зачем функции оборачивают макросами?

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

Или воспользуйтесь поиском по форуму:
DrOffset
6425 / 3799 / 880
Регистрация: 30.01.2014
Сообщений: 6,592
18.02.2014, 20:53     Необходимо разобораться с предопределёнными макросами (компилятор g++) #17
Цитата Сообщение от kravam Посмотреть сообщение
две сущности очень друг на друга похожие- предопределённые макросы и штука, называемая implementation-defined.
Увы нет. implementation-defined - это прилагательное. оно может быть применено например к параграфу про неопределенный порядок аргументов функции. Где implementation-defined, будет означать, что фактический порядок будет зависеть от реализации (implementation) - чего? системы, компилятора, платформы - не важно.

Правильный термин тут predefined variable или predefined identifier. И они совсем не похожи с predefined macro, хоть и внешне можно так подумать. Потому что переменная, константа, идентификатор в программе - это единица языка. А макропоределения, даже предопределенные (predefined) - к языку С++ не осносятся. Это метаязык поверх, он обрабатывает текст, а не только исходный код на с++. То есть для макроса пофиг С++ у тебя, или С или еще что. Он работает с текстом.
Yandex
Объявления
18.02.2014, 20:53     Необходимо разобораться с предопределёнными макросами (компилятор g++)
Ответ Создать тему
Опции темы

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