Открыть список
Как стать автором
Обновить

Комментарии 88

Несколько надуманный «сложный пример» в начале статьи :) А так, да, с опытом уже не испытываешь проблем с прочтением. На смену вопросу «omg, что это?» приходит другой — «omg, зачем так всё усложнять-то?» :)
Такой изврат может понадобится только как средство для запугивания новичков или как билет на экзамене по программированию. Если такое появится в реальном проекте, то стоит задуматься о наличии серьёзных косяков в процессе проектирования.
Я бы даже добавил, что читать-то оно может и не проблема, но понять, то, что ты прочёл — это другая песня. Я б за такую конструкцию человеку из своей команды минимум по рукам надавал, а максимум перевёл такого умника в другой менее критический проект… Код должен быть как песня — всем понятен, лаконичен и каждый чтоб мог «подхватить» чтобы петь хором. 8-)
НЛО прилетело и опубликовало эту надпись здесь
Да, там забавно вообще.
Только вместо foo обычно zval :D
еще и несколько наборов макросов для каждого уровня указателй на zval'ы )))
А зачем это там? Кто-то просто развлекся или подобное имеет под собой основание? Если это так плохо, неужели бы никто до сегодняшнего дня не запатчил бы?
У меня вопрос на счет собственно редакторов кода. VS или еще какие не могут автоматом парсить «сложные типы»? Я сам AS3-кодер и в FDT(Eclipse) работаю. У нас из-за строгой типизации всего (по-хорошему) автокомплит часто очень выручает. Например, при использовании класса Vector.<Class_of_element> или более сложных конструкций:

public var myList : Vector.<Vector.<Vector.<MyClass>>> = new Vector.<Vector.<Vector.<MyClass>>>();

редактор(FDT) при дальнейшем использовании переменной в виде:

myList[0][0][0].автокомплит_по_классу_MyClass;

выдает все верно и как бы парится о том что ты не правильно присвоишь значение не приходится особо. собственно вопрос: В VS, например, так же дела обстоят? Я подумываю над C# изучением как бэкэнда…

P.S.
Vector это типизированный массив. Через двоеточие указывается тип переменной при дефайне, в С++, я так понимаю, он перед переменно пишется.
С++ и C# — разные языки, за последний ничего сказать не могу. На счёт C++ и VS — автокомплит в студии, имхо, весьма убог (в сравнении с FlashDevelop, например), да и сам C++ содержит много неприятных моментов.
Встроенный Intellisens в студии убогенький, но проблема решается VisualAssists
Автокомплит в студии прекрасно работает. В C# работает лучше, чем в C++. В 2010 студии — лучше, чем в 2008
Спасибо. А не знаете он настраивается как нибудь? Через XML, например, как в Eclipse, чтобы прописать пару своих автокомплитов.
Есть мощный инструмент для создания и использования фрагментов кода (code snippets). Можно, например, в коде сниппета оставить параметры вроде имён переменных, по которым можно будет быстро пробежаться кнопкой Tab, приспосабливая вставленный сниппет под свой код.

msdn.microsoft.com/en-us/library/ms165392.aspx
blogs.msdn.com/b/zainnab/archive/2010/04/24/create-new-code-snippets-from-existing-ones-vstiptool0016.aspx
prabathf.blogspot.com/2010/02/code-snippets-in-visual-studio-2010.html
www.4guysfromrolla.com/articles/122105-1.aspx
А кто-то ведь не бросил.
А ещё блин есть typedef, который всё это безобразие заворачивает в более читаемый вид.
Может я и не прав, но техники все таки разные.
Прошу прощения.
Все проще, в си объявления сделаны подобными использованию, т.е.:
long **foo[7];
Должно использоваться как
**foo[n] и будет иметь тип long.
Т.е. указали индекс, два раза разыменовали, получили long.

Аналогично становится легко понять
void (*foo)(int (*bar)(int), float);
(*foo)(&bar, 10.f)
foo это массив из 7 указателей на указателей на значение типа long

Несколько раз перечитывал эту строчку.

Как по мне, так было бы яснее:
foo это массив из 7 указателей на указатели на значение типа long


Или так, но получится с тавтологией:
упс, отправил случайно. Вот недописал:
foo это массив из 7 указателей на указатели, указывающие на значения типа long
Исправил. Но на самом деле я специально оставил это в таком ввиде, чтоб была видна структура алгоритма разбора, что каждый раз дописывается какая либо константа и не надо думать что же следующее и куда его вписать.
А вам часто приходится читать такие объявления?
Нет, но благодаря этой статье я лично на автомате понимаю объявления не очень сложные.
Повторюсь: техники все таки разные, и эта, на мой личный взгляд, проще.
Скоро появится статья на хабре «Как правильно читать.»
Это ниче, вот когда я на химика учился, мы органические соединения называли по их формуле и обратно…
По-моему, с языком что-то не так, если к нему прилагаются десятистраничные мануалы по прочтению объявлений переменных :/
Скорее с программистами, которым доставляет садисткое наслаждение такие штуки писать.
да, с C определенно что-то не так, срочно перестаю его использовать!
Просто не стоит так писать. :/
Поздно… К сожалению, ТАК уже написано много всего…
Страшно ))
Для этого сначала нужно отрефакторить стандартную рефакторилку, а то она не всегда правильно рефакторит.
На самом деле знания действительно полезны. Но все таки если возникает потребность в таких объявлениях, то значит, что-то не так в проектировании ))
Как-же научится правилно писат?
НЛО прилетело и опубликовало эту надпись здесь
А теперь передай это топикстартеру.
Для этого наверно и существует личная почта. И в конце статьи напомнил об этом. Высмеивать чужие ошибки, как это чертовски клёво, не так ли?
Нет, личная почта не для этого.
А прилюдно нужно указать на ошибки, чтобы ДРУГИЕ правильно писали. Неужели непонятно?
Вы часто высмеиваете друзей, когда у них не получается что то, что получается у вас?
Указание на грамматические ошибки имеет целью либо улучшение качества статьи, либо самоутверждение в духе «автор — лох, гыгы».
Для качества статьи лучше писать в личку (будет меньше мусора в комментариях).
Для самоутверждения — устроить прилюдную порку.

P.S. А ссылка на «других» — это лишь попытка придать своим низким действиям возвышенный смысл. Неужели непонятно?
Нет, не самоутверждение, а потому что задолбали безграмотные неучи. Смотришь пост, вроде хороший, а ебанутые ошибки всё портят.
Судя по концентрации ошибок, это был сарказм :)
Я так понимаю, что остально вопросов не вызывает?
что-бы правелно писат, нужно учится учится и учится.
ПробОвать, пробОвать, пробОвать! Откуда эта Ы взялась? Статья неплохая, но следите за русским.
и тире бы везде добавить: foo — это
Сегодня вечером решил взяться за это безобразие, но опустились руки.
И вот статья как на заказ, прочитал, понял, спасибо =)
Да пожалуйста. Искал что то подобное на русском, но не нашел.
Держите тогда заодно и сайтик для проверки: cdecl.org Он помогает такие гадости расшифровывать.
kvs@uv1 ~:> cdecl
Type `help' or `?' for help
cdecl> explain char *(*(**foo[][8])())[]
declare foo as array of array 8 of pointer to pointer to function returning pointer to array of pointer to char
cdecl>
Не понимаю, зачем это надо читать? Важнее понимать что эта штука означает, и как она выглядит в памяти, а для этого лучше всего подходит старый добрый карандаш с листком бумаги. Берем и рисуем квадратики со стрелочками — скажете что примитивно, зато наглядно.
А вообще по рукам(и не только) надо бить за такой код.
бггг, а регекспы читать?
^(\w)|(\@)|(\.)|(\-)
У вас ошибка в регеспе
^(\w|@|\.|-)
это не ошибка, просто данные в разные переменные отлавливал.
— и @ не требуют экранирования.
да, в этом вы правы
Комментаторам-защитникам C и C++: ради бога, смиритесь с тем, что эти языки несовершенны. Объявления в них выглядят стрёмно, и все это знают. Совершенных языков нет, но тот же D в плане объявлений совершеннее:

long**[7] foo, bar, baz;

Вот так следует объявлять foo, bar и baz — массивы из семи указателей на указатели на long, а не заучивать дурацкие правила или прятать весь ужас за typedef. И нет ни дублирования, ни особого порядка чтения. Просто читаешь слева направо, и всё.
«читаешь слева направо»
«long**[7]»
«массивы из»
где же тут слева направо?
long* — указатель
long** — указатель на указатель
long**[7] — массив из семи указателей на указатель

Ну хорошо, можно сказать так: читаешь слева направо, понимаешь в обратном порядке. Всё равно однозначно и более логично, чем это приплюснутое:

long **foo[7];

Здесь вообще нужно читать не слева или справа, а с середины.
>приплюснутое

простите, а при чем тут плюсы? мне кажется, вы немного путаете педали.
И сишное тоже. Цепляетесь к словам моим вы, падаван, мне кажется.
Пожалуйста смиритесь с тем, что примеры в статье надуманы и нужны будут людям, только начинающим учить С++(который конечно не идеален). Думаю ваш оффтоп тут не уместен.
P.S. все же хотелось бы посмотреть объявление char *(*(**foo[][8])())[] на D :D
Те, что в статье — надуманы, но подобные конструкции иногда бывают нужны. Пускай выбор архитектуры останется за человеком, а язык, в первую очередь, должен человеку помогать, а не мешать. Но помогать в меру, не поощряя корявый код. Если можно подобные вещи записать понятнее, пусть в языке будет принята более понятная запись.
Я ведь и не спорю, что С/С++ абсолютный, непогрешимый идеал. Недостатки есть, но тема не о том как здорово в С записываются объявления. Тогда бы ваш коммент был в тему. А выбор языка определяется далеко не только и не столько удобством записи объявлений.
P.S. как все же будет выглядеть запись char *(*(**foo[][8])())[] на D?
Какой же вы бессердечный человек, если хотите, чтобы я распарсил в голове такой кошмар! Доверюсь автору статьи и запишу с его слов:
foo это массив из массив из указателей на указатели на функцию возвращающую указатели на массив из указателей на тип char;

char*[]* delegate() **[8][] foo;

Читаем слева направо:
char
указатель на char
массив указателей на char
указатель на массив указателей на char
функция, возвращающая указатель на массив указателей на char
указатель на функцию, возвращающую указатель на массив указателей на char
указатель на указатель на функцию, возвращающую указатель на массив указателей на char
массив из восьми указателей на указатель на функцию, возвращающую указатель на массив указателей на char
массив из массивов из восьми указателей на указатель на функцию, возвращающую указатель на массив указателей на char
>смиритесь с тем, что эти языки несовершенны

да нам вобщемто глубоко пофигу на проблемы очередных нубов, не прочитавший K&R и лезущих своими трясущимися ручками в божественную благодать сишных сорцов.
Сколько пафоса, ей-богу. Хорошо ещё, что вы не назвали C лучшим языком за всю историю программирования, а то бы я запил от безмерной грусти за человечество.
И тем, кто помнит шуточное якобы интервью со Страуструпом: эта шутка вполне может стать правдой с приходом нового стандарта на C++ (:
В книжке что «Язык программирования С» Функция была для правильного определения с каким объявлением имеешь дело.
Кому интересно вот The C Programming Language
глава называется «5.12 Complicated Declarations»
Первая мысль «Господи, кто ж такое пишет?»
Но дочитав почти до конца успокоился, что даже авторы не используют такое в своих проектах и пример просто с++ скороговорка.
вот такое объявление функции встретить в boost

template<typename T,std::size_t N>
T (*addressof(T (&t)[N]))[N]
{
return reinterpret_cast<T(*)[N]>(&t);
}
Ваш пример понятнее и логичнее. Но я понял к чему вы.
Сколько можно разжевывать правило улитки: на хабре это, как минимум, 3-ья статья.
Как вы переводили :)
Указатель на указателе сидит, и указателем погоняет…
намутил как то.хотел как проще, а в итоге лишь запутал меня. интуитивно ясно же все, не?
Синтаксический анализ на Си есть в классической книге «Язык программирования C» Брайна Кернигана и Денниса Ритчи в конце 5 главы, если кому интересно.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.