Вывод сигнатуры функции

Тема в разделе "LANGS.C", создана пользователем _DEN_, 26 янв 2010.

  1. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Нет не верно, ты мог бы засабмитить баг в МС, но учти что придётся их убедить пунктами стандарта, а не "комо это понимает".
     
  2. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    J0E

    Только не "комо", а "камю" (Comeau). "It is widely regarded as the most standards-conformant C++ compiler." - подсказывает нам википедия. Мне пока что не удалось найти в нем хотя бы один баг, а то, что мне казалось багом, оказалось моим незнанием стандарта.
    Однако, к теме топика это отношения не имеет - баг тут явный, и никакие конкретные пункты стандарта тут не нужны - достаточно сказать что конвенция вызова в стандарте никак не фигурирует, а введенное расширение не должно ломать стандартные конструкции.

    А про сабмит бага в мс это ты хорошо пошутил, спасибо, посмеялся [​IMG]
     
  3. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    А когда падает программа, ты наверно каждый раз нажимаешь кнопку "Отправить отчет", да? :)))
     
  4. nop_

    nop_ New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2007
    Сообщения:
    61
    Этого никто не делает. Немного изменил:

    Код (Text):
    1. struct A
    2. {
    3.   void foo(int, int){}
    4. };
    5.  
    6. void bar(int, int){}
    7.  
    8. int main()
    9. {
    10.   typedef void F(int, int);
    11.  
    12.   F A::* mf = &A::foo;
    13.   F    * pf = &bar;       // <- Вот это делают (и это должно работать)
    14. }
    'F' в любом случае имеет тип 'void(int, int)', который вообще не имет отношения к 'А'.
     
  5. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    _DEN_ ты прав камо к теме отношения не имеет, зачем про него оффтопить. но баги в нем находили.
    Про сабмит в МС я не шутил, делал это сам на connect.microsoft.com заполняешь форму, но надо обосновать, как и любой баг, иначе внимания не обратят и отпишут отговорку.

    nop_ - спасибо, опять туплю :) с адресами напутал.

    Может быть в первом коде и есть какой-то смысл, отличный от №10, но судя по имени check и дальнейшему молчанию ДЭна - он не связан с программированием и С++ в частности.)
     
  6. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    J0E

    Батхерт говорит в тебе. Умей сливать достойно :)
     
  7. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Код (Text):
    1. template <class T, class F>
    2. void check(F T::*)
    3. {
    4.     F* ptr = (F*)&helper;
    5. }
    Воть, VS 2005 конпелирует.
     
  8. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    _DEN_ тю, фишка в том, что я ложил болт, кто что тут обо мне думает ) поэтому уже который раз повторю: я не понимаю нах это надо, ты можешь объяснить? где мешает конвенция вызовов. а до тех пор буду троллить твое ЧСВ, может багрепорты научишся в результате писать ;)

    Booster - это вариант на тему №8, щас Ден нарисует непонятный смайлик ;) и попробуй поиграть c /Gz
     
  9. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    J0E
    Ну так главное, чтобы конпелировалось, шутко ^)
    А вообще я согласен, что VS сливает, gcc тут полностью солидарен с comeu. Хотя не уверен что это именно баг, а не ub. Так как всё конкретизируется в указатель на мембер.
     
  10. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Маленькая правка: s/всё/всё же.

    З.Ы. И всё-таки RO пост это бред.
     
  11. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Есть основание думать, что проблема решена в текущем (post beta2) билде VS 2010.
     
  12. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    green откуда основания, где-то можно его скачать?
    У меня нет вопросов, почему ты называешь багом поведение 2010beta2. Компиль выводит тип шаблона, но потом не может привести к этому типу. Стандарт читать не нужно и так понятно что то тут не то )

    Однако по поводу замысла Дэна я бы с радостью послушал комментарии, смотрю стандарт:

    14.3.2 Template non-type arguments [temp.arg.nontype]
    1 A template-argument for a non-type, non-template template-parameter shall be one of:
    — an integral constant-expression of integral or enumeration type; or
    — the name of a non-type template-parameter; or
    — the address of an object or function with external linkage, including function templates and function
    template-ids but excluding non-static class members, expressed as & id-expression where the & is
    optional if the name refers to a function or array, or if the corresponding template-parameter is a reference;
    or
    — a pointer to member expressed as described in 5.3.1 .
    2 [Note: A string literal (2.13.4) does not satisfy the requirements of any of these categories and thus is not an
    acceptable template-argument. [Example:
    template<class T, char* p> class X {
    // ...
    X();
    X(const char* q) { /* ... */ }
    };
    X<int,"Studebaker"> x1; // error: string literal as template-argument
    char p[] = "Vivisectionist";
    X<int,p> x2; // OK
    —end example] —end note]
    3 [Note: Addresses of array elements and names or addresses of non-static class members are not acceptable
    template-arguments. [Example:
    template<int* p> class X { };
    int a[10];
    struct S { int m; static int s; } s;
    X<&a[2]> x3; // error: address of array element
    X<&s.m> x4; // error: address of non-static member
    X<&s.s> x5; // error: &S::s must be used
    X<&S::s> x6; // OK: address of static member
    —end example] —end note]
     
  13. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Замечание относится к варианту №3. Если это верно то почему компилятор должен выводить типы в первом варианте?
     
  14. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Лан, посмеялись и хватит :) баттхерт, как выражается Дэн, или тяга к знаниям, как скажу я ;) не дает мне спокойно ждать завтра :)

    template<class T> struct S {
    T t;
    };

    template<class T> void f(){
    T t;
    }

    typedef int function();

    S<function> a;

    int main()
    {
    f<function>();
    }

    Видно суслика? Или я теперь уже действительно туплю? )))
     
  15. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    J0E
    Я не поленился запостить этот баг в MS Connect - регрессия относительно 2008, однако. :)
    Вот в такой форме:
    Код (Text):
    1. struct foo
    2. {
    3. void bar() {}
    4. };
    5.  
    6. template <class T>
    7. void check(T foo::*)
    8. {
    9. }
    10.  
    11. void test()
    12. {
    13. check(&foo::bar);
    14. }
    Сказали, что пофиксено уже.

    В данном случае параметр шаблона - именно тип. Общая идея кода _DEN_ и RedLord состоит в том, чтобы из сложного типа "указатель на член структуры" выделить тип, определяющий свойства члена безотносительно его принадлежности к структуре. Так, в
    struct foo
    {
    int m_;
    int f();
    };
    искомый тип для типа указателя на m_ (т.е. int foo::*) будет int, а для типа указателя на f (т.е. int (foo::*)()) - int (*)(). В общем случае, нужно из типа 'T foo::*' получить тип T.

    Для реализации этой идеи _DEN_ использовал выведение типа в функциональных шаблонах, а RedLord - частичную специализацию в классовых шаблонах. В принципе, должны работать оба метода, но оказывается, что второй(частичная специализация) в VC++ реализован лучше. Точнее говоря, RedLord тоже использует выведение, но только для предварительного получения полного исходного типа.

    Что касается соотношения конвенций вызова в T и "T foo::*", то в случае VC++ видно, что компилятор для ф-ции-члена с дефолтной конвенцией (__thiscall) выводит дефолтную конвенцию (определяемую настройками компилятора) для соответствующего типа свободной ф-ции, таким образом обеспечивая корректную компиляцию стандарт-совместимого кода.
     
  16. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Про тип я немного понимаю, см про суслика. Моя идея была почитать стандарт )
     
  17. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    green вообще конечно жалко, что ты ответил раньше Дэна. с моей стороны будет грубостью рассчитывать на твои экстрасенсорные чувства, учитывая твои развернутые ответы, ты не ждешь от людей, что будут тратить свое время на понимание тебя.

    Вот откуда код с сусликом:

    14.3.1 Template type arguments

    3 If a declaration acquires a function type through a type dependent on a template-parameter and this causes
    a declaration that does not use the syntactic form of a function declarator to have function type, the program
    is ill-formed. [Example:
    template<class T> struct A {
    static T t;
    };
    typedef int function();
    A<function> a; // ill-formed: would declare A<function>::t
    // as a static member function
    —end example]
     
  18. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    J0E
    Про суслика, я что-то не пойму, каким боком это сюда относится... Или не относится?

    А вообще, интересно... я не знал про этот пункт Стандарта. IMHO, довольно странно, что запрещается нефункциональная форма декларации ф-ции в шаблонных структурах. Ведь в обычных(нешаблонных) структурах она разрешена. Непоследовательно как-то... Или они испугались слишком большого семантического разброса в разных инстанциациях шаблона, или посчитали слишком сложным анализ такого шаблона компилятором... Скорее всего и то, и как следствие, другое. :derisive:
     
  19. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Суслик это похоже баг в Комяу, который Дэн нашел, сам того не подозревая. Комяу компилирует половину этого примера, а ВЦ полностью, как и ill-formed example из 14.3.1/3. Но я не уверен что следует этот баг сабмитить, в Бусте припоминаю где-то в комментах к function либо typeof про использование багофич.

    В не шаблонных выражениях такое не разрешено то же, поскольку там нет типов, зависимых от параметров шаблона. Или имеются ввиду варианты типа:

    template<class T> S {
    struct inner { T t; };
    };

    но по-моему здесь тип тоже зависим.
     
  20. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    А почему не должно относиться к первому посту? Декларация есть, функциональный тип зависит от параметров шаблона. Синтаксис отличен от определения функционального типа (нет скобочек). Поэтому мне кажется что если нужны какие то определения, то типы для них следует выводить как в №12, разбирая подробно.