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


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


NB>а не при создании первой переменной?


Нет.
Вот смотри ещё 2 аналогичных примера, которые _не_ работают по той же причине:

template<typename type>
struct b {};


template<typename type>
struct d : b<d::inner> 
{
  typedef type inner;
};




template<typename type>
struct b 
{
  typedef typename type::inner inner;
};


template<typename type>
struct d : b<d> 
{
};



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[6]: Невероятно, но факт! Не константные значения в компай
От: Lorenzo_LAMAS  
Дата: 08.02.07 08:35
Оценка: +1
R>

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


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


Да что ты? Она говорит о том, что magic<>::val он один и не меняется. Или нет?


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


Не, я хотел о другом — забавно, я вчера пробовал — и он орал о разыменовании нулевых указателей. Похоже, что это он замечает в relaxed mode.

А вообще, так как всем нам, похоже, одинаково некогда/лень ковыряться в стандарте и искать обоснований тех или иных утверждений, лучше подождать авторитетных мнений: Андрея Тарасевича, Павла Кузнецова, elcste (порядок указания имен произвольный ). Можно спросить на comp.lang.c++.moderated.
Лично для меня очевидно, что поиск имен должен работать всегда одинаково и не зависеть от того, что и сколько раз инстанцировалось.
Of course, the code must be complete enough to compile and link.
Re[6]: Невероятно, но факт! Не константные значения в компай
От: night beast СССР  
Дата: 08.02.07 08:37
Оценка:
Здравствуйте, remark, Вы писали:

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


думаю, что в обявлении friend должно быть что-то, что инстанцирует magic<type,-1> (то есть не указатель)

но если friend действительно вводит нужную функцию в глобальное пространство и это корректно, тогда можно и указатель.

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


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


да вроде находится.
Re[5]: Невероятно, но факт! Не константные значения в компай
От: night beast СССР  
Дата: 08.02.07 08:50
Оценка:
Здравствуйте, remark, Вы писали:

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


NB>>а не при создании первой переменной?


R>Нет.


аналогичный пример
template< typename T, typename S> struct test;

template< typename T, typename S = typename test<T,void>::type >
struct test {
   typedef int type;
};

int main () {
   test<int> x;
}



R>Вот смотри ещё 2 аналогичных примера, которые _не_ работают по той же причине:


не аналогичных. ты тип используешь не в определении default параметра.
Re[9]: Будь твёрд в своей любви!
От: Erop Россия  
Дата: 08.02.07 09:13
Оценка:
Здравствуйте, remark, Вы писали:

R>Априори (без ссылок на стандарт) компилирование 3 самыми популярными и приближенными к стандарту компиляторами чего-то да стоит. По крайней мере того, что бы оппонент представил хотя бы какие-то факты, а не просто фразы, что это типа какая-то там некая давно известная дыра где-то


Ну дыра называется The Barton-Nackman Trick.
Но в этом случае всё происходит изнутри шаблона, всё-таки.
Как именно должны взаимодействовать глобальные функции, объявленные в разных инстанциациях шаблона я в стандарте не нашёл
Может плоъхо искал...

Но в целом, видимо есть, по крайней мере надежда, что стандарт можно и удобно трактовать так, чтобы было счастье. Но будет ли оно --
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Невероятно, но факт! Не константные значения в компайл-т
От: Pavel Chikulaev Россия  
Дата: 08.02.07 09:15
Оценка:
Здравствуйте, remark, Вы писали:

Посмотри всю ветку http://lists.boost.org/Archives/boost/2004/08/70668.php
Re[2]: Невероятно, но факт! Не константные значения в компай
От: Pavel Chikulaev Россия  
Дата: 08.02.07 09:22
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

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


PC>Посмотри всю ветку http://lists.boost.org/Archives/boost/2004/08/70668.php


И вот эту: http://lists.boost.org/Archives/boost/2004/12/77162.php
Re[9]: Невероятно, но факт! Не константные значения в компай
От: Erop Россия  
Дата: 08.02.07 09:27
Оценка:
Здравствуйте, remark, Вы писали:

R>Так же как и всё остальные.

R>Нет понятия каких-то "других" функций, есть просто функции и они все равнозначны и одинакого влияют на разрешение перегрузки.

Сутиь проблемы в следующем.
В С++ шаблоны определены очень запутано и непоследовательно. Например, относительно легко написать код, который будет зависеть не только от точки инстанциации шаблона, но ещё и от последовательности этих инстанциаций.
Когда инстанциации связаны между собой, то вроде как всё специфицировано, но вот когда они несвязаны никак, то, АФАИК это не специфицировано.
В принципе это правильно, так как предоставляет довольно полезную свободу авторам компиляторов. Скажем каждый шаблон, с каждым набором параметров хотя бы предсказуемо инстанцируется.
А так, от порядка инстанциации шаблонов в единице трансляции, начнёт зависеть то, что нужно генерить по шаблонам. Это приведёт к проблемам с ODR, например.

Так что, ИМХО и АФАИК это всё-таки особенность реализации шаблонов в используемых тобой компиляторах.
Например, может сломаться на компиляторе, который компилит все шаблоны в одну базу на проект, а потом оттуда их переиспользует, то может и не сработать
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: Невероятно, но факт! Не константные значения в компай
От: Erop Россия  
Дата: 08.02.07 09:31
Оценка:
Здравствуйте, remark, Вы писали:

R>Вот это вообще не понял.

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

Дырка состоит в том, что у инстанцирования шаблонного класса есть побочный эффект -- появляется объявление нешаблонной функции в объемлющем пространстве имён. На что именно влияет это объявление,а на что не влияет -- это вопрос очень тонкий.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Невероятно, но факт! Не константные значения в компай
От: Lorenzo_LAMAS  
Дата: 08.02.07 09:59
Оценка:
R>Я серьёзно считаю, что поиск имён зависит от того, что видно в POI.

Мне вот тоже влом думать Я написал простой пример:
template<class>
class A
{
   friend void fun(const A<char> *);
};

int main()
{
   A<char> * p = 0;
   fun(p);
}

Комо находит функцию.
Вижуал — лошит — не находит! Зато, если я добавляю
int main()
{
   A<int>a;
   A<char> *p = 0;
   fun(p);
}


Он уже может найти эту функцию. Так вот ты что, утверждаешь, что такое поведение вижуала правильное???
Кстати, а что за бредовую муру пишет вижуал, если сделать так:
int main()
{
   A<char> *p = 0;
   fun(p);
   A<int>a;

}

??
Of course, the code must be complete enough to compile and link.
Re[3]: Невероятно, но факт! Не константные значения в компай
От: Шахтер Интернет  
Дата: 08.02.07 13:42
Оценка:
Здравствуйте, remark, Вы писали:

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


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


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


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


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


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


Я задал конкретный вопрос здесь
Автор: Шахтер
Дата: 07.02.07
.

Пока я не получил ответа.


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


R>Почему?


Потому что нарушаются локальность поведения и принцип однозначности значения шаблона как функции аргументов. Нарушение этих базовых принципов ничем не оправдано.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Невероятно, но факт! Не константные значения в компайл-т
От: jazzer Россия Skype: enerjazzer
Дата: 08.02.07 14:32
Оценка: +3
Здравствуйте, remark, Вы писали:

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


+3 за полет мысли!

P.S. Но мне это категорически не нравится.
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[7]: Невероятно, но факт! Не константные значения в компай
От: Roman Odaisky Украина  
Дата: 08.02.07 16:29
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Лично для меня очевидно, что поиск имен должен работать всегда одинаково и не зависеть от того, что и сколько раз инстанцировалось.


По-моему, тут не всё так просто.

template <class X>
class C
{
    friend void doSomething(X &);
}
(http://rsdn.ru/Forum/Message.aspx?mid=2340657&amp;only=1
Автор: remark
Дата: 08.02.07
)

Зависит ли здесь поиск имен от того, чем инстанцируется C? По-моему, очень даже зависит.
До последнего не верил в пирамиду Лебедева.
Re[6]: Невероятно, но факт! Не константные значения в компай
От: Pavel Chikulaev Россия  
Дата: 08.02.07 16:36
Оценка: 2 (2)
Здравствуйте, Lorenzo_LAMAS, Вы писали:

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


L_L>Мне вот тоже влом думать Я написал простой пример:

L_L>
L_L>template<class>
L_L>class A
L_L>{
L_L>   friend void fun(const A<char> *);
L_L>};

L_L>int main()
L_L>{
L_L>   A<char> * p = 0;
L_L>   fun(p);
L_L>}
 
L_L>

L_L>Комо находит функцию.
L_L>Вижуал — лошит — не находит! Зато, если я добавляю
L_L>
L_L>int main()
L_L>{
L_L>   A<int>a;
L_L>   A<char> *p = 0;
L_L>   fun(p);
L_L>}
L_L>


L_L>Он уже может найти эту функцию. Так вот ты что, утверждаешь, что такое поведение вижуала правильное???

14.6.5/2
[q]
As with non-template classes, the names of namespace-scope friend functions of a class template specialization
are not visible during an ordinary lookup unless explicitly declared at namespace scope (11.4).
Such names may be found under the rules for associated classes (3.4.2).131) [Example:
template<typename T> class number {
public:
number(int);
//...
friend number gcd(const number& x, const number& y);
//...
void g()
{
number<double> a(3), b(4);
//...
a = gcd(a,b); // finds gcd because number<double> is an
// associated class, making gcd visible
// in its namespace (global scope)
b = gcd(3,4); // ill-formed; gcd is not visible
}
 

—end example]
};
[/q]
Re[2]: Невероятно, но факт! Не константные значения в компай
От: Кодт Россия  
Дата: 08.02.07 17:22
Оценка:
Здравствуйте, Шахтер, Вы писали:

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

Ш>2) Если это не баг, то это дыра в стандарте. Срочно фиксить стандарт.
Ш>3) Пользоваться такими изобретениями в реальной работе категорически нельзя. Ломиком по рукам.

Больше всего это похоже на нарушение ODR.
Вот простенький пример, делающий то же самое абсолютно без наворотов.
char foo(...);

int const x = sizeof(foo(char(0)));

int foo(int);

int const y = sizeof(foo(char(0)));

double foo(char);

int const z = sizeof(foo(char(0)));

Разница лишь в том, что мы не автоматически, а вручную ввели новые определения. Ну и количество уточнений ограничено тремя: char < int < ...

И если это действительно ODR, то программа ill-formed, а поведение компилятора не определено. Тот факт, что большинство компиляторов пошли одним путём — поздравляю.
Могли и не пойти, кстати.
// генератор последовательности (любой)
template<bla-bla-bla> struct sequence { bla-bla-bla };

typedef t1 = sequence<>;
typedef t2 = sequence<>;

t1 x1;
t1 x2;
t1 x3;
t2 x4;
t2 x5;
t2 x6;

Если компилятор в точке объявления t1 запоминает все дефолтные параметры, доступные на тот момент, то
— t1 != t2
— typeof(x1) == typeof(x2) == typeof(x3)
А если компилятор полагает, что sequence<> и в африке sequence<>, запоминает, что "вот здесь параметры — дефолтные" и затем разворачивает их по месту использования, то
— t1 эквивалентно t2 (т.е. x4...x6 продолжают серию x1...x3)
— typeof(x1) != typeof(x2) != typeof(x3)
Кстати, от VC<=7.0 можно было ожидать именно такого... Раз уж он шаблоны запоминал как AST без проверок.

А особенно прикольно это будет смотреться, когда шаблон дважды встретится в одном выражении. Который будет какой?
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[3]: Невероятно, но факт! Не константные значения в компай
От: night beast СССР  
Дата: 08.02.07 17:45
Оценка:
Здравствуйте, Кодт, Вы писали:

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


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

Ш>>2) Если это не баг, то это дыра в стандарте. Срочно фиксить стандарт.
Ш>>3) Пользоваться такими изобретениями в реальной работе категорически нельзя. Ломиком по рукам.

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

К>Вот простенький пример, делающий то же самое абсолютно без наворотов.
К>char foo(...);

К>int const x = sizeof(foo(char(0)));

К>int foo(int);

К>int const y = sizeof(foo(char(0)));

К>double foo(char);

К>int const z = sizeof(foo(char(0)));

К>Разница лишь в том, что мы не автоматически, а вручную ввели новые определения. Ну и количество уточнений ограничено тремя: char < int < ...

а где здесь нарушение ODR?
объявлено 3 разных функции.

К>И если это действительно ODR, то программа ill-formed, а поведение компилятора не определено. Тот факт, что большинство компиляторов пошли одним путём — поздравляю.

К>Могли и не пойти, кстати.

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

К>// генератор последовательности (любой)
К>template<bla-bla-bla> struct sequence { bla-bla-bla };

К>typedef t1 = sequence<>;
К>typedef t2 = sequence<>;

К>t1 x1;
К>t1 x2;
К>t1 x3;
К>t2 x4;
К>t2 x5;
К>t2 x6;

К>Если компилятор в точке объявления t1 запоминает все дефолтные параметры, доступные на тот момент, то

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

template< typename T, typename S = typename T::type > struct test;
typedef test<int> error;
Re: Друзья и ADL
От: Roman Odaisky Украина  
Дата: 08.02.07 20:45
Оценка: 1 (1)
Давайте определимся. Что из этого должно работать?

namespace ns
{
    class X
    {
    public:

        friend void testxx(X const& x)
        {
            std::cout << "An X: " << &x << std::endl;
        }

        friend void testx()
        {
            std::cout << "Just a test." << std::endl;
        }
    };
}

class Y
{
public:

    friend void testyy(Y const& y)
    {
        std::cout << "A Y: " << &y << std::endl;
    }

    friend void testy()
    {
        std::cout << "Just a test." << std::endl;
    }
};

int main()
{
    ns::X x;
    testxx(x);
    ns::testxx(x);

    Y y;
    testyy(y);
    ::testyy(x);

    std::cout << (void *)&testy      << std::endl;
    std::cout << (void *)&testyy     << std::endl;
    std::cout << (void *)&ns::testx  << std::endl;
    std::cout << (void *)&ns::testxx << std::endl;

    testy();
    ns::testx();
}
До последнего не верил в пирамиду Лебедева.
Re[6]: Невероятно, но факт! Не константные значения в компай
От: night beast СССР  
Дата: 09.02.07 03:50
Оценка:
Здравствуйте, Pavel Chikulaev, Вы писали:

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


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

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

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


свой резон в этом есть. но что компилятор должен делать в таком случае:
template<typename T>
struct magic
{
    typedef typename remove_ref<T>::type type;

    friend int engine(type);
};
Re[10]: Будь твёрд в своей любви!
От: remark Россия http://www.1024cores.net/
Дата: 09.02.07 05:09
Оценка:
Здравствуйте, Erop, Вы писали:

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


R>>Априори (без ссылок на стандарт) компилирование 3 самыми популярными и приближенными к стандарту компиляторами чего-то да стоит. По крайней мере того, что бы оппонент представил хотя бы какие-то факты, а не просто фразы, что это типа какая-то там некая давно известная дыра где-то


E>Ну дыра называется The Barton-Nackman Trick.

E>Но в этом случае всё происходит изнутри шаблона, всё-таки.
E>Как именно должны взаимодействовать глобальные функции, объявленные в разных инстанциациях шаблона я в стандарте не нашёл
E>Может плоъхо искал...


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


E>Но в целом, видимо есть, по крайней мере надежда, что стандарт можно и удобно трактовать так, чтобы было счастье. Но будет ли оно --


У меня будет, а Вы смотрите сами...


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

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


R>>Так же как и всё остальные.

R>>Нет понятия каких-то "других" функций, есть просто функции и они все равнозначны и одинакого влияют на разрешение перегрузки.

E>Сутиь проблемы в следующем.

E>В С++ шаблоны определены очень запутано и непоследовательно. Например, относительно легко написать код, который будет зависеть не только от точки инстанциации шаблона, но ещё и от последовательности этих инстанциаций.
E>Когда инстанциации связаны между собой, то вроде как всё специфицировано, но вот когда они несвязаны никак, то, АФАИК это не специфицировано.
E>В принципе это правильно, так как предоставляет довольно полезную свободу авторам компиляторов. Скажем каждый шаблон, с каждым набором параметров хотя бы предсказуемо инстанцируется.
E>А так, от порядка инстанциации шаблонов в единице трансляции, начнёт зависеть то, что нужно генерить по шаблонам. Это приведёт к проблемам с ODR, например.

Вот к проблемам с ODR тут ничего не приведёт.
По факту у меня получается не более, чем:
magic<0>::val;
magic<1>::val;
magic<2>::val;


Такой код можно и руками написать.
Тут ODR _не_ нарушается, и следовательно привести к нарушению ODR в будущем не может. Смотри, например, мою реализацию определения смещения членов в классе — все классы, которые зависят от magic — просто тоже становятся разными классами (точнее разными специализациями).

E>Так что, ИМХО и АФАИК это всё-таки особенность реализации шаблонов в используемых тобой компиляторах.

E>Например, может сломаться на компиляторе, который компилит все шаблоны в одну базу на проект, а потом оттуда их переиспользует, то может и не сработать

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


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