Re[8]: Невероятно, но факт! Не константные значения в компай
От: remark Россия http://www.1024cores.net/
Дата: 10.02.07 08:36
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Кстати, на случай, если ты не понял, к чему был мой пример — вот еще один:


L_L>Вижуал выдает странные сообщения об ошибках. У комо все как надо, АДЛ работает.

L_L>Вот так вот работает и VC

L_L>Но это ИМХО говорит лишь о некоторой его кривизне, которую и хочет использовать автор исходного сообщения.


В конце концов на комо никто не работает — все работают на gcc/msvc — а у них такая модель компиляции шаблонов
Кстати в бусте тоже присутствуют всякие нехорошие моменты и затычки — но они ориентируются именно на работоспособность кода хотя бы под двумя компиляторами — причём зачастую работа под двумя компиляторами достигается по разному


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[8]: Aaaaaaaaaaaaaaaaa
От: remark Россия http://www.1024cores.net/
Дата: 10.02.07 08:50
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Кстати, на случай, если ты не понял, к чему был мой пример — вот еще один:


А вот ещё один занятный пример:

char fff(...);

template<typename type> struct X;

void f1()
{
  char a[sizeof(fff((X<int>*)0)) == 1 ? 1 : -1]; (void)a;
}

template<typename type> struct X
{
  friend int fff(X*) {return 0;};
};

int main()
{
  f1();
  char a[sizeof(fff((X<int>*)0)) == 4 ? 1 : -1]; (void)a;
}


Comeau online компилит
К чему я это, я сходу не скажу


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

R>Каким образом там это сломается? У меня ODR нигде не нарушается. Хоть в одну базу их клади, хоть нет, неважно.


У тебя-то ODR не нарушается, но вот, если бы компиляторы работали так, как ты хочешь, то легко бы могла нарушаться.
В этом проблема.
поэтому работать может как-то неожиданно. Ты же довольно тонкой особенностью реализации пользуешься?
НУ а попробовать на трансляторе с общей базой шаблонов я тебе посоветовал потому, что там шаблоны оборабатываются сильно не так, как в GCC, например.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: Невероятно, но факт! Не константные значения в компай
От: Erop Россия  
Дата: 10.02.07 10:18
Оценка:
Здравствуйте, remark, Вы писали:

R>Я надеюсь его работоспособность не вызывает вопросов. Иначе это уже не ко мне.

R>Имхо, если повнимательнее поглядеть на пример, то всё становится достаточно прозрачно.
R>В POI для конкретной специализации friend function выносится в объемлющее пространство. И "ниже" POI эта function может вызываться и участвовать в перегрузке на равне со всеми остальными.

Но ты-то немного другой пример написал...
Ты же находишь другой engine, чем подставляемый...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Невероятно, но факт! Не константные значения в компай
От: Шахтер Интернет  
Дата: 10.02.07 10:23
Оценка: +1
Здравствуйте, remark, Вы писали:

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


Ш>>С чего бы это? У тебя тип параметра не совпадает с типом, в котором продекларирован engine().


R>Отвечаю на конкретный вопрос


R>Похоже тут ты прав.

R>Тогда предлагаю сделать так (тут вроде в этом плане всё чисто):

Да нет, не будет это работать.

char engine(...);

template<typename type>
struct magic_base
{
    friend int engine(magic_base<type>&, type&) {return 0;};
};

template<typename type> type& create();

template<typename type = int, int id = sizeof(engine(create<magic_base<type> >(), create<type>() ))>
struct magic : magic_base<type>
{
    static const int val = id;
};

int main()
{
    char a[magic<>::val 


Эта строчка вызовет следующие действия компилятора

1) magic<> -> magic<int,id> . Вычислить id.
2) id = sizeof ( engine(magic_base<int> &,int &) ) . Найти engine.
3) Первый кандидат -- char engine(...).
4) Включаем ADL. Первый аргумент -- magic_base<int> &. Ищем в пространстве имен magic_base<int>. Для этого инстантинируем magic_base<int>.
5) По ADL находим второго кандидата -- int magic_base<int>::engine(magic_base<int> &,int &).
6) Второй кандидат выигрывает по правилам разрешения перегрузки.
7) id=4



      != magic<>::val ? 1 : -1];

Всё повторится с тем же самым результатом (за тем исключением, что второй раз magic_base<int> инстантинирован не будет).


    (void)a;
}



R>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Для тупых, посните, всё-таки?
От: Erop Россия  
Дата: 10.02.07 10:26
Оценка: +1
Здравствуйте, remark, Вы писали:

R>
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>}
R>


Вот смотри. Я так тебя понял что ты ждёшь, что выделенное неравенство будет соблюдено.
Вот и поясни (без всяких там ссылок на тонкости стандарта), как, по твоему мнению обстоит дело.
Где именно и какие именоо инстанциации инстанциируются. То есть укажи пожалуйста место POI для всех участвующих в процессе шаблонов.

А то я что-то никак не въеду
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Невероятно, но факт! Не константные значения в компай
От: Шахтер Интернет  
Дата: 10.02.07 10:28
Оценка:
Здравствуйте, Кодт, Вы писали:

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


К>>>Больше всего это похоже на нарушение ODR.


R>>Нет-нет! Подождите!

R>>Где ж тут нарушение ODR? Для какого объявления есть более одного определения???

К>Мда, действительно... значит, не оно.


К>Хотя ситуация, когда одно и то же выражение в разных частях одного и того же scope резолвится по-разному — настораживает...


Это плохая практика программирования.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Для тупых, посните, всё-таки?
От: Константин Л.  
Дата: 10.02.07 10:53
Оценка:
Здравствуйте, Erop, Вы писали:

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


R>>
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>>}
R>>


E>Вот смотри. Я так тебя понял что ты ждёшь, что выделенное неравенство будет соблюдено.

E>Вот и поясни (без всяких там ссылок на тонкости стандарта), как, по твоему мнению обстоит дело.
E>Где именно и какие именоо инстанциации инстанциируются. То есть укажи пожалуйста место POI для всех участвующих в процессе шаблонов.

E>А то я что-то никак не въеду


и почему id должен быть всегда разным? не очевидно.
Re[6]: Невероятно, но факт! Не константные значения в компай
От: Erop Россия  
Дата: 10.02.07 10:56
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Да нет, не будет это работать.


Совершенно согласен. только формулировочку можно смягчить на "не обязана работать на соответсвующем стандарту комиляторе".

Идея всего хака в том, что в принципе компилятьору никто не запрещает инстанцировать какие-нибудь левые лаблорны, если ему от чего-то это удобно. И пытаются ловить побочные эффекты таких вот инстациаций, но это все от компилера всё-таки зависит
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Для тупых, посните, всё-таки?
От: Erop Россия  
Дата: 10.02.07 11:21
Оценка:
Здравствуйте, Константин Л., Вы писали:

E>>А то я что-то никак не въеду

КЛ>и почему id должен быть всегда разным? не очевидно.

ИМХО он никогда не должен. И возникает вопрос о том, может ли?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[9]: Aaaaaaaaaaaaaaaaa
От: Lorenzo_LAMAS  
Дата: 12.02.07 08:28
Оценка:
Здравствуйте, remark, Вы писали:

R>А вот ещё один занятный пример:


R>char fff(...);

R>template<typename type> struct X;

R>void f1()
R>{
R>  char a[sizeof(fff((X<int>*)0)) == 1 ? 1 : -1]; (void)a;
R>}

R>template<typename type> struct X
R>{
R>  friend int fff(X*) {return 0;};
R>};

R>int main()
R>{
R>  f1();
R>  char a[sizeof(fff((X<int>*)0)) == 4 ? 1 : -1]; (void)a;
R>}
R>


R>Comeau online компилит

R>К чему я это, я сходу не скажу

Ээээ, я думаю, дело обстоит так. Т.к. f1 у тебя не шаблон, то тут все проще, никаких двухфазных поисков, никаких ПОИ. "Обычный" поиск имен находит функцию с ... . АДЛ ничего не находит (он и не может видеть то, что будет объявлено ниже).

Т.е. аналогично:
#include <iostream>

void fun(...)
{
   std::cout<<"fun(...)\n";
}

struct A;

void g()
{
   A * p = 0;
   fun(p);
}

void fun(A *)
{
   std::cout<<"fun(A *)\n";
}

int main()
{
   g();
}


Вызвана будет fun(...). Ну а в main в твоем исходном примере
у тебя уже есть нужное объявление функции друга, обычный поиск имен его не найдет, его найдет ADL.
Of course, the code must be complete enough to compile and link.
Re[9]: Невероятно, но факт! Не константные значения в компай
От: Lorenzo_LAMAS  
Дата: 12.02.07 08:31
Оценка:
Здравствуйте, remark, Вы писали:

R>В конце концов на комо никто не работает — все работают на gcc/msvc — а у них такая модель компиляции шаблонов

R>Кстати в бусте тоже присутствуют всякие нехорошие моменты и затычки — но они ориентируются именно на работоспособность кода хотя бы под двумя компиляторами — причём зачастую работа под двумя компиляторами достигается по разному

R>




Самое обидное, это когда комо начинает действительно необъяснимо глюкать Такие примеры бывают — вон, недавно что-то спрашивали про sizeof ("такой простой sizeof" или что-то в этом роде, там можно было заметить странное поведение комо)
Of course, the code must be complete enough to compile and link.
Re[12]: Невероятно, но факт! Не константные значения в компа
От: Sm0ke Россия ksi
Дата: 12.02.07 09:53
Оценка:
Здравствуйте, Erop, Вы писали:

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


R>>Каким образом там это сломается? У меня ODR нигде не нарушается. Хоть в одну базу их клади, хоть нет, неважно.


E>У тебя-то ODR не нарушается, но вот, если бы компиляторы работали так, как ты хочешь, то легко бы могла нарушаться.

E>В этом проблема.
E>поэтому работать может как-то неожиданно. Ты же довольно тонкой особенностью реализации пользуешься?
E>НУ а попробовать на трансляторе с общей базой шаблонов я тебе посоветовал потому, что там шаблоны оборабатываются сильно не так, как в GCC, например.

Такой трюк может привести к ODR

рассмотрим пример с 3-мя заголовочными файлами
file_01.h:
#pragma once

#include "magic.h"

struct some1 : pubilc magic<>
{};


file_02.h:
#pragma once

#include "magic.h"

struct some2 : pubilc magic<>
{};


test.h:
#pragma once

#include "magic.h"
// включаем только второй файл (1)
#include "file_02.h"

struct test : pubilc magic<>
{
  typedef
    some2
    type;
  type value;
};


test.cpp
#include "test.h"

// какой-то код


main.cpp
// включаем и первый файл, потом второй, потом test.h
#include "file_01.h"
#include "file_02.h"
#include "test.h"

int main()
{
  test t;
  return 0;
}


Как видно от порядка включения файлов file_01.h и file_02.h меняется определение класса test
Re[13]: Невероятно, но факт! Не константные значения в компа
От: Erop Россия  
Дата: 12.02.07 16:08
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Как видно от порядка включения файлов file_01.h и file_02.h меняется определение класса test


1) Конечно может вызвать .
2) Мало ли порядок включения каких хедеров влияет на компиляцию?

Тут будет влиять ещё и порядок инстанцирования шаблонов в единице трансляции.

Скажем так пишем:

void my_processor( ... );
template<class T>
class MyArray : public std::vector<T> {
    friend void my_processor( T );
public:
    void Process()
    {
        for( int i = 0; i < size(); i++ )
             my_processor( i );
    }
};



И теперь код, вызывающий метод MyArray::Process будет зависеть от того, какие именно MyArray<T> уже были инстанциированы к моменту инстанциации вызова этого метода в данной единице трансляции
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[14]: Невероятно, но факт! Не константные значения в компа
От: night beast СССР  
Дата: 13.02.07 05:31
Оценка:
Здравствуйте, Erop, Вы писали:

E>Скажем так пишем:


E>void my_processor( ... );
E>template<class T>
E>class MyArray : public std::vector<T> {
E>    friend void my_processor( T );
E>public:
E>    void Process()
E>    {
E>        for( int i = 0; i < size(); i++ )
E>             my_processor( i );
E>    }
E>};



E>И теперь код, вызывающий метод MyArray::Process будет зависеть от того, какие именно MyArray<T> уже были инстанциированы к моменту инстанциации вызова этого метода в данной единице трансляции


было бы интересно глянуть, как ты вызываешь MyArray::Process не инстанцировав MyArray
Re[15]: Невероятно, но факт! Не константные значения в компа
От: Erop Россия  
Дата: 13.02.07 12:22
Оценка:
Здравствуйте, night beast, Вы писали:

NB>было бы интересно глянуть, как ты вызываешь MyArray::Process не инстанцировав MyArray


сравни

void f1() { MyArray<char>().Process();
void f2() { MyArray<int>().Process();


void f2() { MyArray<int>().Process();
void f1() { MyArray<char>().Process();
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[16]: Невероятно, но факт! Не константные значения в компа
От: night beast СССР  
Дата: 13.02.07 14:41
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, night beast, Вы писали:


NB>>было бы интересно глянуть, как ты вызываешь MyArray::Process не инстанцировав MyArray


E> сравни


а, вот ты о чем
так вроде уж выяснили, что не работает здесь
Автор: Шахтер
Дата: 10.02.07
Re[17]: Невероятно, но факт! Не константные значения в компа
От: Erop Россия  
Дата: 13.02.07 14:48
Оценка:
Здравствуйте, night beast, Вы писали:

NB>так вроде уж выяснили, что не работает здесь
Автор: Шахтер
Дата: 10.02.07

Так а я о чём?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Ремарки от ремарка :)
От: remark Россия http://www.1024cores.net/
Дата: 14.02.07 20:27
Оценка: +3
Здравствуйте, remark, Вы писали:

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


Ну... вобщем я так понял, что... код всё-таки противоречит стандарту
Особенное спасибо Lorenzo_LAMAS и Pavel Chikulaev за разъяснения и настойчивость

Ну, лично для меня, это осталось по крайней мере очень интересным и познавательным...

Тем не менее похоже, что не работает это исключительно на Comeau. И это остаётся рабочим вариантом на msvc71/msvc80/gcc34/gcc41/icc70/icc80/edg. Впечатляет, правда? Не работает только на самых свежих фронт-ендах edg.
Имхо список компиляторов достаточен даже для включения в boost

Вообще это очень странно. msvc, gcc и icc имеют разные ядра, и тем не менее модель компиляции таких шаблонов у них поразительно одинаково неправильная

R>


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Ремарки от ремарка :)
От: _nn_  
Дата: 17.02.07 13:50
Оценка: :)
Здравствуйте, remark, Вы писали:

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


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


R>Ну... вобщем я так понял, что... код всё-таки противоречит стандарту

R>Особенное спасибо Lorenzo_LAMAS и Pavel Chikulaev за разъяснения и настойчивость

R>Ну, лично для меня, это осталось по крайней мере очень интересным и познавательным...


R>Тем не менее похоже, что не работает это исключительно на Comeau. И это остаётся рабочим вариантом на msvc71/msvc80/gcc34/gcc41/icc70/icc80/edg. Впечатляет, правда? Не работает только на самых свежих фронт-ендах edg.


VC9 Jan CTP. можно тоже включить в список поддерживаемых багофичу
Только бы к релизу не устранили баг
http://rsdn.nemerleweb.com
http://nemerleweb.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.