Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
1

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

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

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

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

Итак, предопределённый макрос __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)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.02.2014, 17:23
Ответы с готовыми решениями:

Переменная с предопределенными значениями
Народ, как объявить переменную, которая будет содержать только определенные значения? Ну,...

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

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

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

16
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
12.02.2014, 10:43  [ТС] 2
Ну что, ребята, какие будут мысли по этому поводу?
0
Псевдослучайный
1946 / 1145 / 98
Регистрация: 13.09.2011
Сообщений: 3,215
12.02.2014, 11:26 3
Очевидно, что невозможно всегда иметь одно и тоже значение для всего файла, поэтому и предоставить что-то вразумительное на вывод этой команды затруднительно.
Более того, конкретно __FUNCTION__ не может обрабатываться препроцессором, ибо он вообще не знает имя текущей функции, то есть макросом в общем-то и не является.
Между тем, __FUNCTION__ — штука нестандартная, зато с С99 и С++11 есть __func__.
2
2062 / 618 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
12.02.2014, 11:38 4
Прикольно! А какие еще есть встроенные макроопределения?
0
18834 / 9836 / 2405
Регистрация: 30.01.2014
Сообщений: 17,274
12.02.2014, 11:53 5
Лучший ответ Сообщение было отмечено kravam как решение

Решение

Цитата Сообщение от 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
2062 / 618 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
12.02.2014, 12:03 6
Почему то не работают...
Bash
__STDC_VERSION__
__OBJC__
__ASSEMBLER__
0
18834 / 9836 / 2405
Регистрация: 30.01.2014
Сообщений: 17,274
12.02.2014, 12:32 7
Цитата Сообщение от programina Посмотреть сообщение
Почему то не работают...
Bash
__STDC_VERSION__
__OBJC__
__ASSEMBLER__
Там в писании все указано В С++ работать не будет.
1
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
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
18834 / 9836 / 2405
Регистрация: 30.01.2014
Сообщений: 17,274
15.02.2014, 22:45 9
Цитата Сообщение от kravam Посмотреть сообщение
А что это? Какая-то незадокументированная конструкция, получается.
Я же дал ссылку на документацию GCC где об этом прямым текстом написано. Даже цитату сюда выписал и жирным подсветил
Конструкция документирована. Просто она не макрос - это предопределенный идентификатор.
Что-то вроде:
C++
1
static const char __FUNCTION__[] = "function-name";
для каждой функции.
0
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
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
18834 / 9836 / 2405
Регистрация: 30.01.2014
Сообщений: 17,274
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
быдлокодер
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,679
17.02.2014, 01:39  [ТС] 12
Цитата Сообщение от DrOffset Посмотреть сообщение
Вроде теперь все на своих местах, нет?
Я буду разбираться, а теперь,то, что на поверхности. Уточнение о терминах:

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

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

А к линуксному пояснению по GCC, обращаться я пока не буду- там ведь тоже некий стандарт, а как мой mingw себя ведёт на самом деле- поди знай.
0
18834 / 9836 / 2405
Регистрация: 30.01.2014
Сообщений: 17,274
18.02.2014, 20:53 17
Цитата Сообщение от kravam Посмотреть сообщение
две сущности очень друг на друга похожие- предопределённые макросы и штука, называемая implementation-defined.
Увы нет. implementation-defined - это прилагательное. оно может быть применено например к параграфу про неопределенный порядок аргументов функции. Где implementation-defined, будет означать, что фактический порядок будет зависеть от реализации (implementation) - чего? системы, компилятора, платформы - не важно.

Правильный термин тут predefined variable или predefined identifier. И они совсем не похожи с predefined macro, хоть и внешне можно так подумать. Потому что переменная, константа, идентификатор в программе - это единица языка. А макропоределения, даже предопределенные (predefined) - к языку С++ не осносятся. Это метаязык поверх, он обрабатывает текст, а не только исходный код на с++. То есть для макроса пофиг С++ у тебя, или С или еще что. Он работает с текстом.
0
18.02.2014, 20:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.02.2014, 20:53
Помогаю со студенческими работами здесь

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

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

Задание с макросами
Помогите, пожалуйста. 2)Для каждого вида продукции определяют одну основную линию его выпуска ....

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

Ошибка с макросами
Помогите решить код, выдает ошибку Dim a, b, c Sub vuchislenia() Dim m, d As String a =...

Работа с макросами
1. В разработанные ранее формы и отчеты вставить по две кнопки для перехода из одной формы (отчета)...


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

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