LINUX.ORG.RU

В C++20 могут появиться макросы, как в Rust

 , ,


1

4

...если комитет примет предложение представленное в этом пропозале.

Предлагается добавить «нативные» C++-макросы.

Из пропозала

So what would one of these native C++ macro functions look like?

 // Macro functions look just like a free function except for the # at the
 // end of the function name. Note that the # counts as part of the identifier,
 // so return# does not collide with the return keyword.
 template<class T>
 inline int return#(T v)
 {
	 if(v > 0)
		return -> v; // control flow keyword + ’->’ means it affects the
	 // calling function, not this macro function
	 if(v < 0)
		break ->;
	 // Also this break is executed in the calling function
	 // If break isn’t valid at the point of use
	 // in the calling function, it will not compile
	 // We can inject variable declarations into the calling function
	 // with typename + ’->’. This is useful for RAII triggered cleanup
	 // i.e. these get destructed when the scope of the call point exits.
	 // Note that the actual name of the variable injected will
	 // be some very unique identifier which cannot collide with any
	 // other variable, including those injected by other macro functions
	 int -> a = 5;
	 // Otherwise this function macro has a local scope, and code
	 // executed here remains here
	 size_t n = 0;
	 for(; n < 5; n++)
	 {
		 // We can also refer to variables previously injected into the
		 // caller’s scope by this macro function like this.
		 // This lets one keep state across invocations of the macro function
		 (-> a) ++;
	 }
	 // This returns a value from this function macro to the caller
	 // If you wrote return -> a, that would be a compile error
	 // as there is no variable called a in this scope.
	 return (-> a);
}

Такие макросы могут быть полезны для реализации некоторых фич, требующих вставки кучи служебного кода, например, корутин или оператора try, без внесения модификаций в Core Language, чисто на уровне библиотек.

Также макросы могут пригодиться для замены обычных макросов, которые станут недоступны после перехода на модули.

Ну ты конечно мастер заголовков. Есть какая-нибудь инфа, что это реально собираются принять?

Также макросы могут пригодиться для замены обычных макросов, которые станут недоступны после перехода на модули.

Недоступны для импорта в другие модули. И то, это лишь один из двух (из трёх) сценариев.

Crocodoom ★★ ()

Также макросы могут пригодиться для замены обычных макросов, которые станут недоступны после перехода на модули.

Мисье, вы забыли про обратную совместимость с C, без которой C++ не особо то и нужен (мне).

SR_team ★★★ ()

Вместо того, чтобы портянку катать, можно было просто запостить вот это:

So what would one of these native C++ macro functions look like?

 // Macro functions look just like a free function except for the # at the
 // end of the function name. Note that the # counts as part of the identifier,
 // so return# does not collide with the return keyword.
 template<class T>
 inline int return#(T v)
 {
	 if(v > 0)
		return -> v; // control flow keyword + ’->’ means it affects the
	 // calling function, not this macro function
	 if(v < 0)
		break ->;
	 // Also this break is executed in the calling function
	 // If break isn’t valid at the point of use
	 // in the calling function, it will not compile
	 // We can inject variable declarations into the calling function
	 // with typename + ’->’. This is useful for RAII triggered cleanup
	 // i.e. these get destructed when the scope of the call point exits.
	 // Note that the actual name of the variable injected will
	 // be some very unique identifier which cannot collide with any
	 // other variable, including those injected by other macro functions
	 int -> a = 5;
	 // Otherwise this function macro has a local scope, and code
	 // executed here remains here
	 size_t n = 0;
	 for(; n < 5; n++)
	 {
		 // We can also refer to variables previously injected into the
		 // caller’s scope by this macro function like this.
		 // This lets one keep state across invocations of the macro function
		 (-> a) ++;
	 }
	 // This returns a value from this function macro to the caller
	 // If you wrote return -> a, that would be a compile error
	 // as there is no variable called a in this scope.
	 return (-> a);
}
anonymous ()

В C++20 могут

Не могут. Новые крупные пропозалы - это в лучшем случае C++26.

как в Rust

Это уже было в Симпсонах

обычных макросов, которые станут недоступны после перехода на модули

Не станут

anonymous ()

Так ведь зачем макросы, если есть шаблоны? :-) Они же Тьюринг полные!!1 :-) На них можно запрограммировать всё что угодно :-) Некоторые громогласно доказывали, что шаблоны - это макросы, но с гигиеной!!1 :-) Некоторые посвятили изучению шаблонов долгие лета, т.к. считалось, что шаблоны - это круто, а макросы - не круто :-) Даже строчки в компайл-тайме на шаблонах можно сгенерить без всяких макросов! :-) И тут вот такая новость :-) Лол :-)

anonymous ()

С++30 появятся иероглифы :-) возможностей клавиатуры явно нехватает..

сколько можно пихать в язык невпихуемое. Стандарт С++ уже превосходит по объёму типовые проекты.

MKuznetsov ★★★★★ ()
Ответ на: комментарий от MKuznetsov

сколько можно пихать в язык невпихуемое. Стандарт С++ уже превосходит по объёму типовые проекты.

На самом деле, в стандартной библиотеке C++ не хватает: GUI для нативных приложений, GUI для мобильных приложений, HTTP/WebSockets сервера :-)

anonymous ()

Хотя, с другой стороны, цепепе сейчас вообще непонятно для чего нужен :-) Разве что только игоря писать :-) В остальном его предназначение не известно :-) Хоть макросы туда добавляй, хоть реактивный двигатель :-) Совершенно непонятно, зачем нужен этот язык, когда столько вокруг альтернатив :-)

anonymous ()

Также макросы могут пригодиться для замены обычных макросов, которые станут недоступны после перехода на модули.

Вот те на. Я обеими руками за модули, но не понимаю, почему из-за их появления надо выкидывать макросы. Это мощный низкоуровневый (хоть и небезопасный) инструмент.

hobbit ★★★★★ ()

Ещё б макросы могли создавать новые макросы + макросы могли иметь compile-time глобальные изменяемые переменные. Вот тогда на них можно было бы сделать всё, что угодно.

KivApple ★★★★★ ()
Ответ на: комментарий от anonymous

А зачем нужны альтереативы, если есть С++? Хипстор чтоле?

А зачем нужен такой язык, в котором, чтобы выполнить банальный HTTP-запрос нужно взять какой-нибудь Beast, накорябать где-то 20 строк кода, потом это умудриться собрать, потом, вытерев лоб от пота, наконец-то запустить в консоли и, если повезёт и не обломаешься, увидеть привет от удалённого HTTP-узла? :-) Очень удобный и продуктивный язык :-) Всем языкам язык, ничего не скажешь :-) А вот когда макросы завезут, так вообще супер удобным и безальтернативным станет :-) Лол :-)

anonymous ()
Ответ на: комментарий от anonymous

На самом деле, в стандартной библиотеке C++ не хватает: GUI для нативных приложений, GUI для мобильных приложений, HTTP/WebSockets сервера :-)

Предлагаешь Qt в стандарт включить?:)

Athor ★★ ()
Ответ на: комментарий от hobbit

ИМХО макросы стоит заменить на кодогенерацию. Т.е. сами #define выкинуть, а операции препроцессора (типа конструирования лексем и объединения строк) оставить. Точно так же, как сейчас оптимизируются константные выражения, должны оптимизироваться выражения с операциями препроцессора:

for (int i = 0; i < 10; i++) prefix ## i .Process ();

||
||
\/

prefix0.Process ();
prefix1.Process ();
prefix2.Process ();
prefix3.Process ();
prefix4.Process ();
prefix5.Process ();
prefix6.Process ();
prefix7.Process ();
prefix8.Process ();
prefix9.Process ();

и т.д. и т.п.

anonymous ()
Ответ на: комментарий от anonymous

https://github.com/whoshuu/cpr

#include <cpr/cpr.h>

int main(int argc, char** argv) {
    auto r = cpr::Get(cpr::Url{"https://api.github.com/repos/whoshuu/cpr/contributors"},
                      cpr::Authentication{"user", "pass"},
                      cpr::Parameters{{"anon", "true"}, {"key", "value"}});
    r.status_code;                  // 200
    r.header["content-type"];       // application/json; charset=utf-8
    r.text;                         // JSON text string
}

Это разве не С++?

anonymous ()

return -> v;
break ->;
int -> a = 5;
return (-> a);

Фак мой мозг. Вот зачем, зачем опять городить контекстную зависимость, теперь уже на оператор доступа к элементу класса по указателю?

Давайте блин уже сделаем следующий шаг, и всё будем делать одним оператором, поставленным в контекстную зависимость. У нас останется только одна проблема: правильно написать контекст, чтобы оператор выполнил то, что нам нужно. Вот это язык получится!

Xintrea ★★★★★ ()
Ответ на: комментарий от Xintrea

Единственная «контекстность», которая появляется — это знание в X -> a = 5 о том, является ли X типом или значением. Не лучше и не хуже X * a.

vzzo ★★★ ()
Последнее исправление: vzzo (всего исправлений: 1)
Ответ на: комментарий от anonymous

# и используется для обозначения макросов.

Так и делали бы единообразно:

template<class T>
 inline int return#(T v)
 {
	 if(v > 0)
		#,return v; // affects the
	 // calling function, not this macro function
	 if(v < 0)
		#,break;
	 // Also this break is executed in the calling function
	 // If break isn’t valid at the point of use
	 // in the calling function, it will not compile
	 int #,a = 5;
...

И скобки лишние не нужны и нет неоднозначности в

foo -> a = 5;

monk ★★★★★ ()
Ответ на: комментарий от vzzo

Не лучше и не хуже X * a

Именно. Но была одна синтаксическая мина, станет две. Останется придумать какие-нибудь действия над типами, обозначающиеся ++ и — и будет совсем хорошо :-)

monk ★★★★★ ()