Свежие новости с C++0x фронта - разбор полётов
От: Masterkent  
Дата: 27.03.10 18:35
Оценка: 32 (6) :))
VladD2:

VD>Меня же во всем в этом веселит тот факт, что набор крайне примитивных изменений не могут принять вот уже 12 лет. За это время уже целое поколение новых языков выросло, а комитет все встречается и встречается...


Насчёт примитивности изменений не соглашусь. Всё-таки составить вменяемые и согласованные друг с другом правила не так-то просто. Однако результативность работы комитета по стандартизации C++ меня сильно удивляет. Чтобы сделать столько оплошностей и годами их не замечать, это нужно иметь талант. Проводить максимально полный разбор полётов я, конечно, не буду (на это бы ушло очень много времени), но несколько примечательных примеров приведу:

  Скрытый текст
1) Ограничения на использование выражений типа void.

N3035 — 3.9.1/9:

Any expression can be explicitly converted to type cv void (5.4). An expression of type void shall be used only as an expression statement (6.2), as an operand of a comma expression (5.18), as a second or third operand of ?: (5.16), as the operand of typeid, or as the expression in a return statement (6.6.3) for a function with the return type void.

Эти два соседние предложения противоречат друг другу: из первого следует, что выражение типа void можно преобразовать к типу void, а из второго следует, что такое преобразование недопустимо (т.к. не подпадает ни под один из пяти вариантов легального использования выражений типа void). Забавно, не правда ли? Но это ещё не всё. Должно ли вот такое дело

template <class Fn, class... Types>
    auto fwd(Fn fn, Types &&... args) ->
        decltype(fn(std::forward<Types>(args)...))
{
    return fn(std::forward<Types>(args)...);
}

работать, если тип выражения fn(std::forward<Types>(args)...) — это void? Фигушки. Применение decltype к выражениям типа void незаконно (такое использование выражений типа void не значится в списке легальных — см. выше). Сильно сомневаюсь, что на это ограничение есть какие-то веские причины — скорее всего, про данный случай просто забыли.

2) Неявное добавление "(*this)."

Допустим, у нас есть структура S c non-static data member-ом m и мы хотим узнать размер S::m. Хорошая новость: теперь вместо зубодробительной конструкции sizeof ((S*)0)->m мы сможем использовать просто sizeof S::m.

N3035 — 5.1.1/10:

An id-expression that denotes a non-static data member or non-static member function of a class can only be used
[...]
— if that id-expression denotes a non-static data member and it appears in an unevaluated operand.
[ Example:

struct S {
  int m;
};
int i = sizeof(S::m);      // OK
int j = sizeof(S::m + 42); // OK

Плохая новость: причудливые правила не разрешают использование таких конструкций в нестатических функциях-членах некоторых классов:

struct B
{
    int m;
};

struct D : B
{
    void f()
    {
        int size = sizeof B::m; // OK
    }
};

struct X
{
    static void f()
    {
        int size = sizeof B::m; // OK
    }
    void g()
    {
        int size = sizeof B::m; // ill-formed
    }
};

Всё дело в том, что по новым правилам любой non-static member в любой non-static member function (независимо от того, к какому классу принадлежит эта функция) должен неявно предваряться конструкцией "(*this).".

N3035 — 9.3.1/3:

When an id-expression (5.1) that is not part of a class member access syntax (5.2.5) and not used to form a pointer to member (5.3.1) is used in the body of a non-static member function of class X, if name lookup (3.4.1) resolves the name in the id-expression to a non-static non-type member of some class C, the id-expression is transformed into a class member access expression (5.2.5) using (*this) (9.3.2) as the postfix-expression to the left of the . operator. [ Note: if C is not X or a base class of X, the class member access expression is ill-formed. —end note ]

Т.е. в нашем случае выражение B::m внутри функции X::g неявно трансформируется в (*this).B::m. Естественно, добавление "(*this)." к совершенно чужому member-у незаконно. Странное дело получается: мы, вроде бы, "(*this)." не пишем, но оно само собой приписывается и делает нашу программу некорректной.

Возникает естественный вопрос: откуда взялись такие правила? Как оказалось, это заслуга автора, который захотел по-быстрому решить проблему, описанную в DR 515. Но что сподвигло его на столь необычное разрешение проблемы (добавлять (*this). к чему ни попадя), остаётся для меня загадкой.

3) Целые статические константы, объявленные с инициализатором в определении класса, всё ещё нуждаются в определении вне класса при их использовании.

В следующем примере

struct X
{
    static int const value = 1;
};

template <class T>
    void f(T const &) { /*....*/ }
    
int main()
{
    f(X::value);
}

попытка формирования ссылки на неопределённый объект может породить ошибку трансляции. По правилам C++03 даже такая программа некорректна:

struct X
{
    static int const value = 1;
};

void f(int) { /*....*/ }
    
int main()
{
    f(X::value);
}

Непременно нужно внешнее определение, а то ж бедный транслятор программы ни за что не догадается, что кто-то использует адрес переменной и под неё-таки нужно выделить маленький клочок памяти (а в случаях, когда адрес не используется, жадно сэкономить несколько байтиков).

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

4) Использование длинных синтаксических конструкций.

Шаблоны в <type_traits> — это какое-то убожество. Если в Boost ещё хоть как-то боролись с синтаксическими нагромождениями (например, см. boost::enable_if vs boost::enable_if_c), то здесь же всюду нужно дописывать ::value и ::type (в последнем случае ещё и typename приходится использовать, если есть зависимость от параметров шаблона). Что, к примеру, мешает определить is_pointer и enable_if следующим образом?

template <class T>
    struct is_pointer_impl : false_type {};
template <class T>
    struct is_pointer_impl<T *> : true_type {};
template <class T>
    struct is_pointer_impl<T *const> : true_type {};
template <class T>
    struct is_pointer_impl<T *volatile> : true_type {};
template <class T>
    struct is_pointer_impl<T *const volatile> : true_type {};
template <class T>
    constexpr bool is_pointer()
        { return is_pointer_impl<T>::value; }

template <bool b, class T = void>
    struct enable_if_impl;
template <class T>
    struct enable_if_impl<true, T>
        { typedef T type; };
template <bool b, class T = void>
    using enable_if = typename enable_if_impl<b, T>::type;

Мы могли бы использовать эти шаблоны примерно так:

template <class T>
    enable_if<is_pointer<T>()> f(T);

А вот так выглядит аналогичное использование стандартных шаблонов в их нынешнем виде:

template <class T>
    typename enable_if<is_pointer<T>::value>::type f(T);

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



В общем, пристально изучая черновик, в нём можно заметить очень много недостатков. Если бы правила C++ верстались на коленке парой человек в течение пары лет, то такой расклад не казался бы странным. Но, поскольку над стандартом работает международный комитет по стандартизации, да ещё и на протяжении многих лет, вся эта халтура выглядит как-то несерьёзно.

Остаётся лишь добавить, что чем раньше выйдет новый стандарт, тем больше в нём останется незалатанных дыр, так что в скором выходе стандарта есть свои минусы.

30.03.10 18:29: Ветка выделена из темы Свежие новости с C++0x фронта
Автор: alexeiz
Дата: 14.03.10
— Кодт
Re[3]: Core Language Active Issues, Revision 69
От: Masterkent  
Дата: 30.03.10 15:58
Оценка: 78 (2)
Похоже, в последнее время люди из комитета стали активнее интересоваться тем, что пишут на comp.std.c++ и comp.lang.c++.moderated. Вот 4 новых репорта по моим темам:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1005
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1055
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1059
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1068
Re[3]: Свежие новости с C++0x фронта - разбор полётов
От: jazzer Россия Skype: enerjazzer
Дата: 31.03.10 06:11
Оценка: 6 (1)
Здравствуйте, Masterkent, Вы писали:

M>Был я и на comp.std.c++, и на comp.lang.c++.moderated. Пока что issue report создан только по одной проблеме:


M>Так что я даже особо не надеюсь на то, что в комитете обозначенными мной вопросами кто-то заинтересуется. Мои темы там создаются, скорее, из любопытства — мало ли, может, я упустил чего из виду, и тогда кто-нибудь мне на это укажет.


А ты не пробовал товарищам из комитета писать непосредственно на их е-мейлы?
Я вот пробовал — они вполне быстро и по делу отвечают.
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[5]: Свежие новости с C++0x фронта - разбор полётов
От: jazzer Россия Skype: enerjazzer
Дата: 31.03.10 09:11
Оценка: 6 (1)
Здравствуйте, Masterkent, Вы писали:

J>>А ты не пробовал товарищам из комитета писать непосредственно на их е-мейлы?


M>Не, не пробовал. Но подумывал об этом. Мне казалось, что в группах мои вопросы и так на виду у товарищей из комитета и игнорирование ими этих вопросов означает лишь то, что они им не интересны.


Ну они же живые люди, работающие в комитете на добровольных началах; у них у всех есть своя работа, личная жизнь и т.д.
Они могут по любой личной причине легко пропустить в группах тот день, в который ты обсуждал свои находки.
Плюс они будут очень рады, если человек не просто задает вопрос или высказывает соображение, а присылает патч к стандарту (proposed wording).
Т.е. ты запостил свою находку в группу, там обсудили, согласились, что баг — просто напиши любому члену комитета (но, конечно, лучше тому, кто именно этой проблематикой занимается, у них на сайте был список, кто чем) письмо со своими выкладками, мнением ньюз-группы, и предлагаемыми изменениями.
Так ему будет гораздо легче вынести это на обсуждение на очередном заседании комитета, и получить окончательное решение.
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]: Свежие новости с C++0x фронта - разбор полётов
От: alexeiz  
Дата: 31.03.10 16:14
Оценка: +1
Здравствуйте, Masterkent, Вы писали:

...

Мне интересно, чем таким надо заниматься, чтобы находить подобные проблемы в стандарте? Я посмотрел пару DRs, и честно говоря, с наскоку достаточно трудно понять, о чем идет речь.
Re: Свежие новости с C++0x фронта - разбор полётов
От: alexeiz  
Дата: 27.03.10 18:59
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>Насчёт примитивности изменений не соглашусь. Всё-таки составить вменяемые и согласованные друг с другом правила не так-то просто. Однако результативность работы комитета по стандартизации C++ меня сильно удивляет. Чтобы сделать столько оплошностей и годами их не замечать, это нужно иметь талант. Проводить максимально полный разбор полётов я, конечно, не буду (на это бы ушло очень много времени), но несколько примечательных примеров приведу:


На этом форуме твои замечания никто не услышит, а вот на comp.std.c++ они могли бы принести пользу.
Re[2]: Свежие новости с C++0x фронта - разбор полётов
От: Masterkent  
Дата: 27.03.10 20:09
Оценка:
alexeiz:

A>На этом форуме твои замечания никто не услышит, а вот на comp.std.c++ они могли бы принести пользу.


Был я и на comp.std.c++, и на comp.lang.c++.moderated. Пока что issue report создан только по одной проблеме:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#978

Так что я даже особо не надеюсь на то, что в комитете обозначенными мной вопросами кто-то заинтересуется. Мои темы там создаются, скорее, из любопытства — мало ли, может, я упустил чего из виду, и тогда кто-нибудь мне на это укажет.
Re[4]: Свежие новости с C++0x фронта - разбор полётов
От: Masterkent  
Дата: 31.03.10 08:52
Оценка:
jazzer:

J>А ты не пробовал товарищам из комитета писать непосредственно на их е-мейлы?


Не, не пробовал. Но подумывал об этом. Мне казалось, что в группах мои вопросы и так на виду у товарищей из комитета и игнорирование ими этих вопросов означает лишь то, что они им не интересны.

J>Я вот пробовал — они вполне быстро и по делу отвечают.


Видимо, ты прав: стоит попробовать.
Re[6]: Свежие новости с C++0x фронта - разбор полётов
От: Masterkent  
Дата: 31.03.10 12:09
Оценка:
jazzer:

J>Плюс они будут очень рады, если человек не просто задает вопрос или высказывает соображение, а присылает патч к стандарту (proposed wording).


Не всегда просто предложить хорошую формулировку. Я недостаточно хорошо изучил черновик, поэтому запросто могу что-нибудь упустить (как, в общем-то, и из-за банальной забывчивости). Мне уже довелось обнаружить два случая, когда попытка устранить дефект в правилах привела к появлению нового дефекта:

1) разрешение проблемы в DR 515 стало причиной неясностей, описанных в issue 1005 и issue 1017

2) Предложенная в DR 641 формулировка (которая присутствует в нынешнем черновике)

Proposed Resolution (October, 2007):

Change the footnote in 12.3.2 [class.conv.fct] paragraph 1 as follows:

некорректна, т.к. описанные преобразования, за исключением lvalue-to-rvalue преобразований, никогда не являются стандартными.

Вот, кстати, ещё один забавный перл, который я и Андрей Тарасевич обнаружили независимо друг от друга:

С++03 — 14.7/5:

No program shall explicitly instantiate any template more than once, both explicitly instantiate and explicitly specialize a template, or specialize a template more than once for a given set of template-arguments.

N3092 — 14.7/5:

For a given template and a given set of template-arguments,
— an explicit instantiation definition shall appear at most once in a program,
— an explicit specialization shall be defined at most once in a program (according to 3.2), and
— both an explicit instantiation and a declaration of an explicit specialization shall not appear in a program unless the explicit instantiation follows a declaration of the explicit specialization.

Из этих правил следует, что мы даже не имеем права подключать следующие заголовочные файлы стандартной библиотеки

<limits> (содержит определение специализации std::numeric_limits<bool>),
<memory> (содержит определение специализации std::allocator<void>),
<string> (содержит определение специализации std::char_traits<char>),
<locale> (содержит определение специализации std::ctype<char>), and
<complex> (содержит определение специализации std::complex<float>)

в более чем одну единицу трансляции каждый, потому что иначе программа будет содержать более одного определения явной специализации одного и того же шаблона с одними и теми же аргументами. Видимо, автор этих правил напрочь забыл про существование специализаций шаблонов классов и inline-функций. Удивительно, что данная странность не была замечена даже при пересмотре формулировки.
Re[8]: Свежие новости с C++0x фронта - разбор полётов
От: Masterkent  
Дата: 31.03.10 16:33
Оценка:
alexeiz:

A>Мне интересно, чем таким надо заниматься, чтобы находить подобные проблемы в стандарте?


Эти проблемы сами собой обнаруживаются при внимательном прочтении. Каких-то специальных поисков дефектов в правилах я не веду.
Re[9]: Свежие новости с C++0x фронта - разбор полётов
От: alexeiz  
Дата: 31.03.10 18:04
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>alexeiz:


A>>Мне интересно, чем таким надо заниматься, чтобы находить подобные проблемы в стандарте?


M>Эти проблемы сами собой обнаруживаются при внимательном прочтении. Каких-то специальных поисков дефектов в правилах я не веду.


Я имел ввиду, может ты над компилятором работаешь или имеешь дело с библиотеками, где всплывают эти дефекты?
Re[5]: Свежие новости с C++0x фронта - разбор полётов
От: remark Россия http://www.1024cores.net/
Дата: 02.04.10 16:47
Оценка:
Здравствуйте, Masterkent, Вы писали:

J>>А ты не пробовал товарищам из комитета писать непосредственно на их е-мейлы?


M>Не, не пробовал. Но подумывал об этом. Мне казалось, что в группах мои вопросы и так на виду у товарищей из комитета и игнорирование ими этих вопросов означает лишь то, что они им не интересны.


J>>Я вот пробовал — они вполне быстро и по делу отвечают.


M>Видимо, ты прав: стоит попробовать.



Пиши сюда:
http://www.justsoftwaresolutions.co.uk/cplusplus/c++0x-now-at-fcd.html
BSI предлагает всем сообщать комментарии на тему:

* Suggestions for how to improve the clarity of the wording, even if that's just by adding a cross-reference to a relevant paragraph elsewhere;
* Comments that identify any under/over specification; and
* Comments highlighting inconsistencies or contradictions in the draft text.

А они их обработают и передадут от себя в ISO.
В третий раз сообщил им, что они в С1х и C++0x называют mutex'ы lock'ами в 1.10, интересно с какого раза поправят


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[10]: Свежие новости с C++0x фронта - разбор полётов
От: remark Россия http://www.1024cores.net/
Дата: 02.04.10 17:00
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>>>Мне интересно, чем таким надо заниматься, чтобы находить подобные проблемы в стандарте?

M>>Эти проблемы сами собой обнаруживаются при внимательном прочтении. Каких-то специальных поисков дефектов в правилах я не веду.
A>Я имел ввиду, может ты над компилятором работаешь или имеешь дело с библиотеками, где всплывают эти дефекты?


Из моего опыта, когда я работал над Relacy Race Detector (это верификатор алгоритмов синхронизации, который очень точно симулирует модель памяти C++0x), ошибки в 1.10 (Multi-threaded executions and data races) всплывали стаями. В каких-то случаях пишешь-пишешь код, а в какой-то момент понимаешь, что не можешь понять, что тебе писать дальше, т.е. какой-то момент недоопределен. К каких-то — приходишь к каким-то противоречиям в описании. В каких-то — вникаешь очень подробно в описанную формальную семантику, и понимаешь, что она достаточно странная, и навряд ли они этого хотели.



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