GCC patch: "static_print"
От: Skorodum Россия  
Дата: 04.07.17 12:43
Оценка: 4 (2)
static-print

This is a patch to the GCC 7.1 source which adds a "static_print" statement to C++.

The static_print statement can be used wherever static_assert can be used, and its effect is to print a formatted message at compile time.

static_print can receive any no. of arguments, each argument being either a string literal (which is printed out), or any "template-argument" expression (anything that could be a template argument — types, constant expressions, template names, etc..), which is resolved at compile time and pretty-printed.

Unlike static_assert, static_print also behaves correctly with if constexpr! (nothing will be printed if the condition does not apply).

Example:

template<typename T, int s>
struct test
{
    static_print("The template ", ::test, " has been instantiated as ", test, ". By the way, s + 1 is ", s + 1);
};

int main() {
    test<int, 3> y;
    return 0;
}


Compiling the above program prints out (at compile time):

The template test has been instantiated as test<int, 3>. By the way, s + 1 is 4

gcc c++
Re: GCC patch: "static_print"
От: kov_serg Россия  
Дата: 04.07.17 19:33
Оценка:
Здравствуйте, Skorodum, Вы писали:

S>static-print


А можно как-то тип перменной вывести, что бы далеко не лазить?

Типа такого:
#include <string>
std::string foo() { return ""; }

//------------------------------

struct WTF {};

int main() {
    auto a=foo();
    WTF(a);
    return 0;
}

...
error: ‘a’ has a previous declaration as ‘std::basic_string<char> a’
...

=> std::basic_string<char> a;
Re[2]: GCC patch: "static_print"
От: Skorodum Россия  
Дата: 05.07.17 07:59
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>А можно как-то тип перменной вывести, что бы далеко не лазить?

Так он же это и делает

The template test has been instantiated as test<int, 3>. By the way, s + 1 is 4

Re[3]: GCC patch: "static_print"
От: kov_serg Россия  
Дата: 05.07.17 08:25
Оценка:
Здравствуйте, Skorodum, Вы писали:

S>Здравствуйте, kov_serg, Вы писали:


_>>А можно как-то тип перменной вывести, что бы далеко не лазить?

S>Так он же это и делает
S>

S>The template test has been instantiated as test<int, 3>. By the way, s + 1 is 4

А он пишет в какой строке исходного файла он это вывел?
terra/incognito/some_place.cpp:100500:12: static_print: The template test has been instantiated as test<int, 3>. By the way, s + 1 is 4
Re[4]: GCC patch: "static_print"
От: Skorodum Россия  
Дата: 05.07.17 08:33
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>А он пишет в какой строке исходного файла он это вывел?

_>
_>terra/incognito/some_place.cpp:100500:12: static_print: The template test has been instantiated as test<int, 3>. By the way, s + 1 is 4
_>

Судя по примеру нет, но наверняка это не сложно сделать
Re[5]: GCC patch: "static_print"
От: kov_serg Россия  
Дата: 05.07.17 14:25
Оценка: +3 :))) :))) :)
Здравствуйте, Skorodum, Вы писали:

S>Здравствуйте, kov_serg, Вы писали:


_>>А он пишет в какой строке исходного файла он это вывел?

_>>
_>>terra/incognito/some_place.cpp:100500:12: static_print: The template test has been instantiated as test<int, 3>. By the way, s + 1 is 4
_>>

S>Судя по примеру нет, но наверняка это не сложно сделать

Вобще полумеры какие-то. С нетерпением ждём static_exec
Re: GCC patch: "static_print"
От: B0FEE664  
Дата: 05.07.17 22:40
Оценка: 3 (1) :))
Здравствуйте, Skorodum, Вы писали:

S>

S>

S>static_print can receive any no. of arguments, each argument being either a string literal (which is printed out), or any "template-argument" expression (anything that could be a template argument - types, constant expressions, template names, etc..), which is resolved at compile time and pretty-printed.
S>

S>The template test has been instantiated as test<int, 3>. By the way, s + 1 is 4


Следующий шаг — перенаправить вывод в новый файл и подсунуть его компилятору на компиляцию...
Т.е. можно получить кодогенерацию в момент компиляции с помощью компилятора:

template<typename T, int s>
struct test_generator
{
    static_print("struct test_", s, " { char m_name[", s + 1, "]; };");
};



Сдаётся мне, что это прямая альтернатива метаклассам
Автор: Alexander G
Дата: 29.06.17
.
И каждый день — без права на ошибку...
Re[2]: GCC patch: "static_print"
От: alex_public  
Дата: 08.07.17 13:38
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Следующий шаг — перенаправить вывод в новый файл и подсунуть его компилятору на компиляцию...

BFE>Т.е. можно получить кодогенерацию в момент компиляции с помощью компилятора:

BFE>
BFE>template<typename T, int s>
BFE>struct test_generator
BFE>{
BFE>    static_print("struct test_", s, " { char m_name[", s + 1, "]; };");
BFE>};
BFE>



Зачем так извращаться, если в D уже есть более простой и отлично работающий механизм — функция mixin. На мой взгляд её давным давно пора засунуть в C++. Хотя нет, в начале всё же надо ещё разрешить в C++ полноценную работу со строками во время компиляции.
Re[2]: GCC patch: "static_print"
От: Alexander G Украина  
Дата: 08.07.17 15:54
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Сдаётся мне, что это прямая альтернатива метаклассам
Автор: Alexander G
Дата: 29.06.17
.


Русский военный корабль идёт ко дну!
Re[3]: GCC patch: "static_print"
От: _NN_ www.nemerleweb.com
Дата: 12.07.17 12:19
Оценка: +1
Здравствуйте, alex_public, Вы писали:

_>Зачем так извращаться, если в D уже есть более простой и отлично работающий механизм — функция mixin. На мой взгляд её давным давно пора засунуть в C++. Хотя нет, в начале всё же надо ещё разрешить в C++ полноценную работу со строками во время компиляции.


Не надо такого.
Лучше дать нормальный API и работать через него.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: GCC patch: "static_print"
От: alex_public  
Дата: 12.07.17 21:15
Оценка:
Здравствуйте, _NN_, Вы писали:

_>>Зачем так извращаться, если в D уже есть более простой и отлично работающий механизм — функция mixin. На мой взгляд её давным давно пора засунуть в C++. Хотя нет, в начале всё же надо ещё разрешить в C++ полноценную работу со строками во время компиляции.

_NN>Не надо такого.
_NN>Лучше дать нормальный API и работать через него.

Так mixin — это и есть нормальный API для генерации кода средствами метапрограммирования.
Re[5]: GCC patch: "static_print"
От: jazzer Россия Skype: enerjazzer
Дата: 14.07.17 05:17
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Так mixin — это и есть нормальный API для генерации кода средствами метапрограммирования.


костыли это, а не API
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: GCC patch: "static_print"
От: alex_public  
Дата: 15.07.17 00:23
Оценка:
Здравствуйте, jazzer, Вы писали:

_>>Так mixin — это и есть нормальный API для генерации кода средствами метапрограммирования.

J>костыли это, а не API

Ну тогда приведи пример, как выглядели бы не костыли. )

Кстати, данных костылей вполне хватает для реализации например такого https://github.com/rejectedsoftware/diet-ng/ DSL (естественно речь про встраиваемый прямо в язык, а не внешний препроцессор).
Re[5]: GCC patch: "static_print"
От: _NN_ www.nemerleweb.com
Дата: 16.07.17 07:52
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Так mixin — это и есть нормальный API для генерации кода средствами метапрограммирования.


Мы кстати про какие миксины говорим?
String mixin точно не нужен.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[6]: GCC patch: "static_print"
От: alex_public  
Дата: 16.07.17 14:56
Оценка:
Здравствуйте, _NN_, Вы писали:

_>>Так mixin — это и есть нормальный API для генерации кода средствами метапрограммирования.

_NN>Мы кстати про какие миксины говорим?
_NN>String mixin точно не нужен.

Да, речь именно про них. А что ты считаешь лучшей альтернативой такому решению? Естественно оставаясь в рамках компилятора C++ (без всяких внешних препроцессоров)...
Re[7]: GCC patch: "static_print"
От: jazzer Россия Skype: enerjazzer
Дата: 16.07.17 15:52
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, jazzer, Вы писали:


_>>>Так mixin — это и есть нормальный API для генерации кода средствами метапрограммирования.

J>>костыли это, а не API

_>Ну тогда приведи пример, как выглядели бы не костыли. )


Как в .NET, например. Когда есть, собственно, API (т.е. объекты, методы и прочая), а не просто текстовые макросы:
CodeMemberMethod clearEntityMethod = new CodeMemberMethod();
genClass.Members.Add(clearEntityMethod);
clearEntityMethod.Name = "ClearEntity";
clearEntityMethod.ReturnType = new CodeTypeReference(typeof(void));
clearEntityMethod.Parameters.Add(new CodeParameterDeclarationExpression(entityType, "entity"));


_>Кстати, данных костылей вполне хватает для реализации например такого https://github.com/rejectedsoftware/diet-ng/ DSL (естественно речь про встраиваемый прямо в язык, а не внешний препроцессор).


Не сомневаюсь. Мне сишного препроцессора тоже до сих пор хватало (при помощи Boost.Preprocessor, конечно), но тем не менее это костыли.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[8]: GCC patch: "static_print"
От: alex_public  
Дата: 16.07.17 16:36
Оценка:
Здравствуйте, jazzer, Вы писали:

_>>Ну тогда приведи пример, как выглядели бы не костыли. )

J>Как в .NET, например. Когда есть, собственно, API (т.е. объекты, методы и прочая), а не просто текстовые макросы:
J>
J>CodeMemberMethod clearEntityMethod = new CodeMemberMethod();
J>genClass.Members.Add(clearEntityMethod);
J>clearEntityMethod.Name = "ClearEntity";
J>clearEntityMethod.ReturnType = new CodeTypeReference(typeof(void));
J>clearEntityMethod.Parameters.Add(new CodeParameterDeclarationExpression(entityType, "entity"));
J>


Ну так это в рантайме — совсем не то (и кстати реализуется в C++ без каких-либо правок языка/компилятора, только мало кому нужно). Или ты имел ввиду, что сделать набор таких типов и функций, доступных для выполнения во время-компиляции (типа static_assert)? Ну и даже если сделать так (получится как бы ещё один встроенный язык, который надо будет как-то отделять от основного), то в чём ты видишь преимущество такого подхода для метапрограммирования времени компиляции?
Re[7]: GCC patch: "static_print"
От: _NN_ www.nemerleweb.com
Дата: 16.07.17 18:52
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, _NN_, Вы писали:


_>>>Так mixin — это и есть нормальный API для генерации кода средствами метапрограммирования.

_NN>>Мы кстати про какие миксины говорим?
_NN>>String mixin точно не нужен.

_>Да, речь именно про них. А что ты считаешь лучшей альтернативой такому решению? Естественно оставаясь в рамках компилятора C++ (без всяких внешних препроцессоров)...

Что значит в рамках компилятора ? Любая фича выходит за рамки того, что есть сейчас.
Лучшей альтернативой было бы нормальное квази-цитирование.
Т.е. построение дерева выражения за тебя.

Вместо такого:
string makeStruct(string name)
{
 return "struct " + name + "{" + "}" + ";"; // Что если в name передать плохое имя ?;)
}


Был бы код типа:
StructExpression makeStruct(string name)
{
 return <[ struct $name {}; ]>
}

Где этот код вызывается на этапе компиляции и выдаёт вменяемые ошибки в случае чего.

Что-то в стиле варианта C++ Metaclasses
Автор: Alexander G
Дата: 29.06.17


Да, это ещё один язык в языке C++.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[8]: GCC patch: "static_print"
От: alex_public  
Дата: 17.07.17 09:16
Оценка:
Здравствуйте, _NN_, Вы писали:

_>>Да, речь именно про них. А что ты считаешь лучшей альтернативой такому решению? Естественно оставаясь в рамках компилятора C++ (без всяких внешних препроцессоров)...

_NN>Что значит в рамках компилятора ? Любая фича выходит за рамки того, что есть сейчас.

Имеется в виду, что в рамках изменения самого компилятора, а не навешиванием внешних инструментов (типа Qt MOC).

_NN>Лучшей альтернативой было бы нормальное квази-цитирование.

_NN>Т.е. построение дерева выражения за тебя.
_NN>Вместо такого:
_NN>
_NN>string makeStruct(string name)
_NN>{
_NN> return "struct " + name + "{" + "}" + ";"; // Что если в name передать плохое имя ?;)
_NN>}
_NN>


В D в этом случае будет ошибка компиляции со вполне вменяемым сообщением. Единственный минус тут в том, что указывать ошибка будет на строчку с mixin, а не на функцию makeStruct.

_NN>Был бы код типа:

_NN>
_NN>StructExpression makeStruct(string name)
_NN>{
_NN> return <[ struct $name {}; ]>
_NN>}
_NN>

_NN>Где этот код вызывается на этапе компиляции и выдаёт вменяемые ошибки в случае чего.

Это похоже ближе к макросам Rust или Nim. И оно конечно приятнее, но требует по сути введения нового языка в компилятор C++. Я в принципе не против, но сомневаюсь что на такое пойдут. А вот добавить одну скромную и несложную функцию типа mixin по идее могли бы...

_NN>Что-то в стиле варианта C++ Metaclasses
Автор: Alexander G
Дата: 29.06.17


Метаклассы мне понравились. Особенно то, что все текущие стандартные и нестандартные (типа Qt или сериализаций из Boost) сущности в них укладываются. Но это всё равно заметно более узкий подход, чем возможность генерации произвольного кода.
Re[9]: GCC patch: "static_print"
От: _NN_ www.nemerleweb.com
Дата: 17.07.17 09:25
Оценка:
Здравствуйте, alex_public, Вы писали:


_>В D в этом случае будет ошибка компиляции со вполне вменяемым сообщением. Единственный минус тут в том, что указывать ошибка будет на строчку с mixin, а не на функцию makeStruct.

Потом появятся библиотеки для объектного создания этого дела и будет:
string makeStruct(string name)
{
 return createStruct(name).addField(makeField("int", "x")).build();
}


Я даже уверен, что кто-то такое сделал.
Только типизация пропадает сразу после выхода из этой функции да и писать такой код вместо цитирования неочень приятно.

_>Это похоже ближе к макросам Rust или Nim. И оно конечно приятнее, но требует по сути введения нового языка в компилятор C++. Я в принципе не против, но сомневаюсь что на такое пойдут. А вот добавить одну скромную и несложную функцию типа mixin по идее могли бы...

Всё остальное это полумеры.
Можно конечно решить где предел, как шаблоны C++, шаблоны D, а можно сразу сделать как надо и получить все плюшки.

Кстати в Rust насколько я понял там нет отладки, максимум это: cargo-expand.
Я говорю про такие, которые можно отлаживать, как в Nemerle, например.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[10]: GCC patch: "static_print"
От: alex_public  
Дата: 17.07.17 15:02
Оценка:
Здравствуйте, _NN_, Вы писали:

_>>В D в этом случае будет ошибка компиляции со вполне вменяемым сообщением. Единственный минус тут в том, что указывать ошибка будет на строчку с mixin, а не на функцию makeStruct.

_NN>Потом появятся библиотеки для объектного создания этого дела и будет:
_NN>
_NN>string makeStruct(string name)
_NN>{
_NN> return createStruct(name).addField(makeField("int", "x")).build();
_NN>}
_NN>

_NN>Я даже уверен, что кто-то такое сделал.
_NN>Только типизация пропадает сразу после выхода из этой функции да и писать такой код вместо цитирования неочень приятно.

Возможно. Но для людей имеющих в данный момент метапрограммирование только на шаблонах C++ и такое может показаться замечательным. )

_>>Это похоже ближе к макросам Rust или Nim. И оно конечно приятнее, но требует по сути введения нового языка в компилятор C++. Я в принципе не против, но сомневаюсь что на такое пойдут. А вот добавить одну скромную и несложную функцию типа mixin по идее могли бы...

_NN>Всё остальное это полумеры.
_NN>Можно конечно решить где предел, как шаблоны C++, шаблоны D, а можно сразу сделать как надо и получить все плюшки.

Ну я уже писал раньше, что как раз являюсь сторонниками "максимального" развития метапрограммирования в C++. Однако я при этом ещё и реалист. Так что предпочту получить хоть что-то (например аналог mixin из D), чем не получить ничего, предаваясь мечтаниям о полноценных синтаксических макросах.

_NN>Кстати в Rust насколько я понял там нет отладки, максимум это: cargo-expand.

_NN>Я говорю про такие, которые можно отлаживать, как в Nemerle, например.

На мой взгляд для отладки подобных вещей гораздо полезнее наличие отладочной печати. Кстати, для решения типа mixin в этой роли хватило бы как раз static_print из данной темки. А вот для полноценных макросов нужно уже что-то типа print_ast, что впрочем тоже не особая проблема.
Re[11]: GCC patch: "static_print"
От: _NN_ www.nemerleweb.com
Дата: 17.07.17 19:10
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Ну я уже писал раньше, что как раз являюсь сторонниками "максимального" развития метапрограммирования в C++. Однако я при этом ещё и реалист. Так что предпочту получить хоть что-то (например аналог mixin из D), чем не получить ничего, предаваясь мечтаниям о полноценных синтаксических макросах.

Это пройденный этап.
"Александреску" появится гораздо раньше чем кажется.

Поэтому лучше сразу по максимуму.
Тогда и код проще будет и полезности больше.

_>На мой взгляд для отладки подобных вещей гораздо полезнее наличие отладочной печати. Кстати, для решения типа mixin в этой роли хватило бы как раз static_print из данной темки. А вот для полноценных макросов нужно уже что-то типа print_ast, что впрочем тоже не особая проблема.

У меня есть опыт в отлаживании макросов и могу сказать, что это гораздо лучше чем полумеры вида print_ast
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: GCC patch: "static_print"
От: Кодт Россия  
Дата: 24.07.17 09:00
Оценка: 8 (1)
Здравствуйте, Alexander G, Вы писали:

AG>Image: tricky-twisted.jpg

Билл Гейтс показывает на пальцах рогатую сферу Александера
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.