Re[2]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 07.02.07 21:41
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>как я понял каждое выражение magic<>::val должно инстанциировать magic заново и sizeof(engine(*(magicc*)0, *(type*)0)) выдавать новые значение?

КЛ>Все равно не очень понятно

Если на пальцах, то примерно так:

При каждом упоминании magic<>::val заного вычисляется значение аргумента по-умолчанию, причём вычисляется оно именно в той точке, где написано magic<>::val.
И выдаёт это вычисление разные результаты, т.к. предыдущая специализация magic внесла новую перегрузку функции engine.
Как-то так...



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 07.02.07 21:41
Оценка: 1 (1)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

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


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

G>>.......
R>>>


G>>м-да.

G>>а я думал я знаю си++

L_L>Тут речь идет о специфических глюканах компиляторов, к С++ не имеющих отношения, так что не расстраивайся.


Можно поподробнее и поаргументированнее.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 07.02.07 21:49
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

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


PC>[snipped]


PC>Смотри ветку http://rsdn.ru/Forum/?mid=1653980&amp;flat=0
Автор: Pavel Chikulaev
Дата: 01.02.06


... да действительно всё уже украдено до нас... но Chez явно не разглядел потенциал фичи.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: Невероятно, но факт! Не константные значения в компай
От: night beast СССР  
Дата: 07.02.07 22:49
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

NB>>вопрос по выделенному. при замене *(magicc*)0 на magicc() получаем одинаковые magic<>::val.

NB>>чем вызвано?

RO>это-то понятно. rvalue не привязывается к неконстантной ссылке. Здесь кошернее всего писать так:


да, так понятней.
в принципе, второй параметр не нужен:
template<typename type = int, int id = sizeof( engine( make< magic<type,-1> >() ) ) >
struct magic {
    friend int engine( magic<type,-1> );
    static const int val = id;
};
Re[3]: Невероятно, но факт! Не константные значения в компай
От: Pavel Chikulaev Россия  
Дата: 08.02.07 07:26
Оценка:
Здравствуйте, remark, Вы писали:

R>Не понял мысль.

R>По-моему, эта цитата подтверждает работоспособность моего кода.
R>Да, я объявляю все дружественные функции в глобальном пространстве имён. Всё правильно.
R>Да, потом я её нахожу, т.к. тип параметра функции есть сам этот класс (если быть совсем точным, то не сам этот класс, а другая специализация этого же шаблона, но касательно областей видимости имён это ничего не меняет).

R>


Объясню на примере IROVа http://rsdn.ru/Forum/Message.aspx?mid=2338001&amp;only=1
Автор: IROV..
Дата: 07.02.07

typedef struct {} _false;
typedef struct {} _true;

char engine( ... );

template<int id = sizeof( engine( _true() ) )>
struct magic
{
    friend int engine(_true);
    static const int val = id; //*
};

int main()
{
    char a[magic<>::val != magic<>::val ? 1 : -1];
}

friend int engine(_true); в magic<int> объявляет функцию в глобальном пространстве еще до инстанирования шаблона согласно 7.3.1.2/3, поэтому код абсолютно равнозначен этому:
typedef struct {} _false;
typedef struct {} _true;

char engine( ... );
int  engine(_true);

template<int id = sizeof( engine( _true() ) )>
struct magic
{
    static const int val = id; //*
};

int main()
{
    char a[magic<>::val != magic<>::val ? 1 : -1];
}

Именно поэтому на комо это не работает. В VC же баг, там он действительно добавляется лишь после инстанцирования.
Re[2]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 08.02.07 07:38
Оценка:
Здравствуйте, Шахтер, Вы писали:

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


R>>Пришло время очередного ресёрча


Ш>Хочу влить свою бочку дегтя в эту ложку сахарного сиропа.


Ш>1) Я пока не увидел доказательства того, что это standard-compliant поведение. По-моему -- баг.


Какие моменты у тебя вызывают недоверие?

Ш>2) Если это не баг, то это дыра в стандарте. Срочно фиксить стандарт.


Почему?

Ш>3) Пользоваться такими изобретениями в реальной работе категорически нельзя. Ломиком по рукам.


С такими тезисами обращайся в Философию, там можно такое обсудить на пару сотен постов Или лучше сразу в холивары Покрайней мере к С++ это отношения не имеет.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 08.02.07 07:40
Оценка:
Здравствуйте, night beast, Вы писали:

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


R>>Так вот, всё это неправда!

R>>Сейчас вы увидите, как на стандартном с++ можно иметь переменные значения в компайл-тайм!

NB>
R>>char engine(...);

R>>template<typename, int> struct magic;
R>>typedef magic<char, -1> magicc;

R>>template<typename type = int, int id = sizeof(engine(*(magicc*)0, *(type*)0))>
R>>struct magic
R>>{
R>>    friend int engine(magicc&, type&);
R>>    static const int val = id;
R>>};

R>>int main()
R>>{
R>>    char a[magic<>::val != magic<>::val ? 1 : -1];
R>>}
NB>


NB>вопрос по выделенному. при замене *(magicc*)0 на magicc() получаем одинаковые magic<>::val.

NB>чем вызвано?

Чем компилил? Это вообще не должно компилироваться, т.к. ты пытаешься сделать вызов конструктора до определения класса. Там, где ты написал magicc() видно только форвард объявление класса...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 08.02.07 07:41
Оценка:
Здравствуйте, Tonal-, Вы писали:

T>g++ (GCC) 3.4.5 (mingw special)

T>Нет обещанного чуда:
T>
T>C:\tect>g++ -Wall -o "mag" "mag.cpp"
T>mag.cpp:13: warning: friend declaration `int engine(magicc&, type&)' declares a non-template function
T>mag.cpp:13: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning
T>mag.cpp: In function `int main()':
T>mag.cpp:21: warning: unused variable 'a'
T>


Что ты имеешь в виду?
Да, gcc выдал пару вполне законных варнингов, но они не то что бы особо принципиальные. Если они тебе сильно мешают — можешь их пофиксить...



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 08.02.07 07:52
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

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


R>>Не понял мысль.

R>>По-моему, эта цитата подтверждает работоспособность моего кода.
R>>Да, я объявляю все дружественные функции в глобальном пространстве имён. Всё правильно.
R>>Да, потом я её нахожу, т.к. тип параметра функции есть сам этот класс (если быть совсем точным, то не сам этот класс, а другая специализация этого же шаблона, но касательно областей видимости имён это ничего не меняет).

R>>


PC>Объясню на примере IROVа http://rsdn.ru/Forum/Message.aspx?mid=2338001&amp;only=1
Автор: IROV..
Дата: 07.02.07

PC>
PC>typedef struct {} _false;
PC>typedef struct {} _true;

PC>char engine( ... );

PC>template<int id = sizeof( engine( _true() ) )>
PC>struct magic
PC>{
PC>    friend int engine(_true);
PC>    static const int val = id; //*
PC>};

PC>int main()
PC>{
PC>    char a[magic<>::val != magic<>::val ? 1 : -1];
PC>}
PC>


Во-первых, тут ошибка, т.к. friend engine() не должна находится без ADL, т.е. это бы при любом раскладе не стало бы работать. Но это так мелочи.

PC>friend int engine(_true); в magic<int> объявляет функцию в глобальном пространстве еще до инстанирования шаблона согласно 7.3.1.2/3, поэтому код абсолютно равнозначен этому:

PC>
PC>typedef struct {} _false;
PC>typedef struct {} _true;

PC>char engine( ... );
PC>int  engine(_true);

PC>template<int id = sizeof( engine( _true() ) )>
PC>struct magic
PC>{
PC>    static const int val = id; //*
PC>};

PC>int main()
PC>{
PC>    char a[magic<>::val != magic<>::val ? 1 : -1];
PC>}
PC>


Нет, это абсолютно не равнозначно.

PC>Именно поэтому на комо это не работает. В VC же баг, там он действительно добавляется лишь после инстанцирования.


Подсказка 1.

template<typename type>
struct magic
{
    friend int engine(type);
};


Сколько это определение шаблонного класса должно _сразу_ вынести функций в глобальное пространство имён? Для всего бесконечного возможного набора типов, которыми когда-либо могут параметризовать этот шаблон?

Подсказка 2.

Подумай о POI. Когда в первый раз компилятор начинает компилировать специализацию шаблона. И когда он действительно видет, что какую-то функцию надо выносить в глобальное пространство, и видит какую именно. До POI, т.е. пока не требуется определения класса, компилятор не то что не обязан, он не может компилировать специализацию.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Невероятно, но факт! Не константные значения в компай
От: Sm0ke Россия ksi
Дата: 08.02.07 07:56
Оценка:
А почему не зделать так?:
template<typename type = int, int id = sizeof( engine( new magic<type,-1> ) ) >
struct magic {
    friend int engine( magic<type,-1> * );
    static const int val = id;
};
Re[3]: Невероятно, но факт! Не константные значения в компай
От: Аноним  
Дата: 08.02.07 08:11
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, Шахтер, Вы писали:


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


R>>>Пришло время очередного ресёрча


Ш>>Хочу влить свою бочку дегтя в эту ложку сахарного сиропа.


Ш>>1) Я пока не увидел доказательства того, что это standard-compliant поведение. По-моему -- баг.


R>Какие моменты у тебя вызывают недоверие?



Для начала — разыменование нулевого указателя.

R>Почему?


Ты что, серьезно считаешь, что поиск имен зависит от того, что было инстанцировано, а что нет?

Ш>>3) Пользоваться такими изобретениями в реальной работе категорически нельзя. Ломиком по рукам.


R>С такими тезисами обращайся в Философию, там можно такое обсудить на пару сотен постов Или лучше сразу в холивары Покрайней мере к С++ это отношения не имеет.


Код с UB уже тоже.
Re[5]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 08.02.07 08:11
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>А почему не зделать так?:

S>
S>template<typename type = int, int id = sizeof( engine( new magic<type,-1> ) ) >
S>struct magic {
S>    friend int engine( magic<type,-1> * );
S>    static const int val = id;
S>};
S>


Повторяешь ошибку Chez'a и Gurtovoy — с указателем функция не будет находится по ADL


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Невероятно, но факт! Не константные значения в компай
От: Lorenzo_LAMAS  
Дата: 08.02.07 08:12
Оценка:
R>Можно поподробнее и поаргументированнее.

А ты комо онлайн запусти в стрикт режиме и увидишь много интересного.
Of course, the code must be complete enough to compile and link.
Re[5]: Невероятно, но факт! Не константные значения в компай
От: Pavel Chikulaev Россия  
Дата: 08.02.07 08:13
Оценка:
Здравствуйте, remark, Вы писали:

R>Подсказка 1.


R>
R>template<typename type>
R>struct magic
R>{
R>    friend int engine(type);
R>};
R>


R>Сколько это определение шаблонного класса должно _сразу_ вынести функций в глобальное пространство имён? Для всего бесконечного возможного набора типов, которыми когда-либо могут параметризовать этот шаблон?

Да именно так, т.е. равнозначно этому (кроме прав доступа)
template<typename type>
int engine(type);

template<typename type>
struct magic
{
};


R>Подумай о POI. Когда в первый раз компилятор начинает компилировать специализацию шаблона. И когда он действительно видет, что какую-то функцию надо выносить в глобальное пространство, и видит какую именно. До POI, т.е. пока не требуется определения класса, компилятор не то что не обязан, он не может компилировать специализацию.

Это единственное исключение, но это так, т.е. компилятор должен пропускать все в шаблоне кроме друзей.
Re[5]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 08.02.07 08:15
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

R>>Можно поподробнее и поаргументированнее.


L_L>А ты комо онлайн запусти в стрикт режиме и увидишь много интересного.


"ComeauTest.c", line 9: warning: "int engine(magicc &, type &)" declares a
non-template function -- add <> to refer to a template instance
friend int engine(magicc&, type&);
^


Пожалуйста, мне не жалко


"ComeauTest.c", line 15: error: the size of an array must be greater than zero
char a[magic<>::val != magic<>::val ? 1 : -1];
^


Ошибка ни о чём не говорит. Где и что конкретно не так.


"ComeauTest.c", line 15: warning: variable "a" was declared but never referenced
char a[magic<>::val != magic<>::val ? 1 : -1];
^


Аааа... ты про это мне хотел сказать???


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[6]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 08.02.07 08:19
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

PC>Да именно так, т.е. равнозначно этому (кроме прав доступа)

PC>
PC>template<typename type>
PC>int engine(type);

PC>template<typename type>
PC>struct magic
PC>{
PC>};
PC>


Уж вот этому точно не равнозначно. Однозначно.
Тут шаблонная функция, а у меня не шаблонная. А это две большие разницы.

R>>Подумай о POI. Когда в первый раз компилятор начинает компилировать специализацию шаблона. И когда он действительно видет, что какую-то функцию надо выносить в глобальное пространство, и видит какую именно. До POI, т.е. пока не требуется определения класса, компилятор не то что не обязан, он не может компилировать специализацию.

PC>Это единственное исключение, но это так, т.е. компилятор должен пропускать все в шаблоне кроме друзей.

А можно ссылку на стандарт или ещё куда-то?
А если друг в шаблонном клсее, который вложен в другой шаблонный класс???... Ему придётся компилировать ещё и вложенный шаблонный класс??? ... Если вложенный шаблонный класс как-то хитро зависит от параметров шаблона объемлющего?...
Не очень понятно, как это должно/может работать...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: Невероятно, но факт! Не константные значения в компа
От: Lorenzo_LAMAS  
Дата: 08.02.07 08:20
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, Аноним, Вы писали:


А>>Я думаю, Комо, а скорее всего, последний фронт-энд от едг (у Комо он какой-то древний уже). Уж если ЕДГ и глючит, то в совсем уж нетривиальных моментах.

А>>Автор упомянул ЕДГ, но я не понял, что это значит — купить его простым смертным — малореально

R>EDG C++ это компилирует

R>здесь

R>

Хехе, у них версия фронт-энда старее, чем у Комо онлайн.
Of course, the code must be complete enough to compile and link.
Re[3]: Невероятно, но факт! Не константные значения в компай
От: night beast СССР  
Дата: 08.02.07 08:20
Оценка:
Здравствуйте, remark, Вы писали:

NB>>вопрос по выделенному. при замене *(magicc*)0 на magicc() получаем одинаковые magic<>::val.

NB>>чем вызвано?

R>Чем компилил?


гсс 3.4

R>Это вообще не должно компилироваться, т.к. ты пытаешься сделать вызов конструктора до определения класса. Там, где ты написал magicc() видно только форвард объявление класса...


а не при создании первой переменной?
Re[3]: Невероятно, но факт! Не константные значения в компай
От: Tonal- Россия www.promsoft.ru
Дата: 08.02.07 08:20
Оценка:
Опаньки, протупил.
Re[4]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 08.02.07 08:21
Оценка:
Здравствуйте, Аноним, Вы писали:

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


R>>Здравствуйте, Шахтер, Вы писали:


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


R>>>>Пришло время очередного ресёрча


Ш>>>Хочу влить свою бочку дегтя в эту ложку сахарного сиропа.


Ш>>>1) Я пока не увидел доказательства того, что это standard-compliant поведение. По-моему -- баг.


R>>Какие моменты у тебя вызывают недоверие?



А>Для начала — разыменование нулевого указателя.


Пуристы могут заменить это разыменование на вызов функции:
magicc& get_some_magic();


R>>Почему?


А>Ты что, серьезно считаешь, что поиск имен зависит от того, что было инстанцировано, а что нет?


Я серьёзно считаю, что поиск имён зависит от того, что видно в POI.

Ш>>>3) Пользоваться такими изобретениями в реальной работе категорически нельзя. Ломиком по рукам.


R>>С такими тезисами обращайся в Философию, там можно такое обсудить на пару сотен постов Или лучше сразу в холивары Покрайней мере к С++ это отношения не имеет.


А>Код с UB уже тоже.


Кроме нулевой ссылки ещё что-то есть?


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.