Это не баг, а фича компилятора, в режиме edit-and-continue он раскрывает __LINE__ не как числовой литерал, а как целочисленную переменную плюс смещение.
Управляется опцией /Zi, по умолчанию включенной в дебаге.
Выбери вместо неё что-нибудь другое, и будет тебе счастье.
Свойства проекта, С++, отладочная информация — где-то там.
внутри макроса в одной строке у меня вызывается __LINE__ три раза и он должен выдавать три одинаковые значения а при следующем применении макроса он должен выдавать три других числа и так далее...
чем его можно заменить ?
и почему вот такой код работает и никаких ошибок не выскакивает? правда число увеливается в 10 раз...
как бы так сделать чтобы число соответствовало __LINE__ ?
#define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b)
#define BOOST_PP_CAT_I(a, b) a ## b
#define WTF() []() { \
\
printf("%d\n", BOOST_PP_CAT(__LINE__, 0)); \
\
} ()
int _tmain(int argc, _TCHAR* argv[])
{
WTF();
return 0;
}
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>нет, правильный вопрос звучит так J>как на этапе препроцессинга получить рандомное число от 1 до 255 (для последующей конкатенации с именем переменной с помощью ##) ?
Во-первых, отключить edit-n-continue, от него всё равно пользы немного.
Во-вторых, есть __COUNTER__
В-третьих, чтобы он трижды подставился одинаково, надо сделать так
А вот чтобы получить число строго в каком-то интервале, на стадии препроцессора, — тут извиняйте, штатных средств нет.
Могу лишь предложить сделать отдельный дополнительный препроцессор (элементарно: скрипт на перле или питоне), который будет работать или до, или после сишного препроцессора и выдавать лексемы — литералы от 1 до 255.
Если нужны не лексемы, то можно ведь и так поступить
#define UNIQUE_VAR_AND_VALUE_(n) int C(var_,n) = (n) % 255 + 1;
#define UNIQUE_VAR_AND_VALUE() UNIQUE_VAR_AND_VALUE_(__COUNTER__)
UNIQUE_VAR_AND_VALUE() // int var_254 = 254;
UNIQUE_VAR_AND_VALUE() // int var_255 = 255;
UNIQUE_VAR_AND_VALUE() // int var_256 = 1;
Либо, если это какая-то достаточно узкая задача с лексемами, можно припахать циклы из BOOST_PP. Они как раз до 255 умеют считать.
Поэтому расскажи, зачем тебе оно понадобилось.
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>нет, правильный вопрос звучит так J>как на этапе препроцессинга получить рандомное число от 1 до 255 (для последующей конкатенации с именем переменной с помощью ##) ?
// test.cpp : Defines the entry point for the console application.
//#include <tchar.h>
#include <iostream>
extern size_t __declspec(thread) __LINE__Var = 0;
#define __LINE__Var __LINE__Var
#define WTF() { \
\
printf("%d\n", __LINE__); \
\
}
#define WTF2() []() { \
\
printf("%d\n", __LINE__); \
\
} ()
int _tmain(int argc, _TCHAR* argv[])
{
WTF();
WTF();
WTF2(); // line 6 in main
WTF2(); // line 8 in main
WTF();
WTF();
WTF2(); // line 15 in main
WTF2(); // line 17 in mainreturn 0;
}
при включённом Edit and Continue вывод:
25
27
6
8
34
36
15
17
при выключённом Edit and Continue вывод:
25
27
30
32
34
36
39
41
Думаю в данном случае лямбды работают криво и их лучше не юзать для этого.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Не понял, в чём здесь прикол? Зачем ты надуваешь компилятор?
V>Думаю в данном случае лямбды работают криво и их лучше не юзать для этого.
Думаю, что криво работают не сами лямбда, а именно edit-n-continue. Эта фича не соответствует стандарту и реализована непрозрачно и непредсказуемо.
Кстати, надо бы проверить, как она дружит не только с лямбдами, но и с обычными вложенными функциями:
#include <iostream>
using namespace std;
#define SHOW() (cout<<__LINE__<<endl)
int main() {
SHOW(); // 7auto f = [ ]() { SHOW(); };
auto g = [=]() { SHOW(); };
auto h = [&]() { SHOW(); };
struct I { void operator()() { SHOW(); } } i;
SHOW(); // 14
f(); g(); h(); i(); // 9 10 11 12
SHOW(); // 16
f(); g(); h(); i(); // 9 10 11 12
SHOW(); // 18
}
К>Не понял, в чём здесь прикол?
Ну так компилятор ругается что не нашёл переменную, вот я её и подсунул. А дефайн здесь не нужен, это лоскуты от предыдущих тестов.
К>Зачем ты надуваешь компилятор?
Ему значит можно меня надумать, а мне его нет?
V>>Думаю в данном случае лямбды работают криво и их лучше не юзать для этого. К>Думаю, что криво работают не сами лямбда, а именно edit-n-continue. Эта фича не соответствует стандарту и реализована непрозрачно и непредсказуемо.
Ну, лябды появились позже edit-n-continue, так что логичнее, что именно их плохо тестировали.
К>потому что понятно, что там творчески расставлены определения этой переменной, её присваивания и смещения относительно базы.
Так это понятно почему сделано. Если для разных лямбд результат будет одинаковый, то старые макросы генерирующие уникальность через __LINE__ могли бы сломаться в новом коде.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Кодт, Вы писали:
К>Поэтому расскажи, зачем тебе оно понадобилось.
нужно было зашивать в имена переменных определяемых макросом рандомное число...
линкер генерирует мап файл, используя который утилита запускаемая в пост буилд находила
эти перменные и обрабатывала особым образом...
но решил совсем другим способом, как оказалось достаточно дать просто уникальные имена а рандомные
числа генерирует сама утилита при обработке, зашивая key для расшифровки вызывающему коду