avva: (Default)
[personal profile] avva
Будет интересно только программистам, знающим C++.

Небольшая загадка. Предугадайте, что напечатает следующая программа, не запуская ее. Потом проверьте себя, если интересно. Комменты не скрываются.
#include <iostream> #include <map> #include <string> using namespace std; int main() { map<int, string> m; double d = 123456.789; m[0] = d; cout << "m[0]=" << m[0]; return 0; }

Date: 2010-06-26 05:15 pm (UTC)
From: [identity profile] lpetrazickis.livejournal.com
программисты которые не знают C++ хотят знать ответ.

Date: 2010-06-26 06:25 pm (UTC)
From: [identity profile] senecarus.livejournal.com
Они не программисты.

(no subject)

From: [identity profile] gaus.livejournal.com - Date: 2010-06-26 06:56 pm (UTC) - Expand
(deleted comment)

(no subject)

From: [identity profile] psilogic.livejournal.com - Date: 2010-06-26 08:06 pm (UTC) - Expand

(no subject)

From: [identity profile] lykac.livejournal.com - Date: 2010-06-28 09:30 pm (UTC) - Expand

Date: 2010-06-26 05:18 pm (UTC)
From: [identity profile] nmoroz.livejournal.com
Только не говорите, что он найдет какой-то символ по такому числу.

Date: 2010-06-26 05:27 pm (UTC)
From: [identity profile] spamsink.livejournal.com
Чего ж не найти-то?

Date: 2010-06-26 05:36 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Какой символ оно найдёт мне не сообразить, но тут будет double-int-char цепочка.
gcc, гад, даже с -Wall молчит ка крыба об лёд.

Date: 2010-06-26 05:41 pm (UTC)
nine_k: A stream of colors expanding from brain (Default)
From: [personal profile] nine_k
Если 12, то это form feed, экран должна очистить.

(no subject)

From: [identity profile] blacklion.livejournal.com - Date: 2010-06-26 05:42 pm (UTC) - Expand

Date: 2010-06-26 08:15 pm (UTC)
From: (Anonymous)
/usr/local/gcc-3.4.2/bin/g++ -c -Wall -Wno-format-y2k -g -fPIC

warning: passing `double' for converting 1 of `std::basic_string
[Error: Irreparable invalid markup ('<_chart,>') in entry. Owner must fix manually. Raw contents below.]

/usr/local/gcc-3.4.2/bin/g++ -c -Wall -Wno-format-y2k -g -fPIC

warning: passing `double' for converting 1 of `std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]'

(no subject)

From: [identity profile] meshko.livejournal.com - Date: 2010-06-26 08:16 pm (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-06-26 10:52 pm (UTC) - Expand

Date: 2010-06-26 05:40 pm (UTC)
From: [identity profile] msh.livejournal.com
поскольку operator= бывает для string&, char* и char, d превратится в char с предупреждением от компилятора. Какой конкретно char - не знаю, но явно ничего хорошего

Date: 2010-06-26 05:42 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Ну вот g++ не даёт никаких предупреждений. MS/Intel под рукой нет, через 10 минут попробую в clang, который славится своей ворчливостью и правильностью этой ворчливости, если он вообще такой C++ съест (не факт).

(no subject)

From: [identity profile] shadow-at-night.livejournal.com - Date: 2010-06-26 05:52 pm (UTC) - Expand

(no subject)

From: [identity profile] msh.livejournal.com - Date: 2010-06-26 05:56 pm (UTC) - Expand

(no subject)

From: [identity profile] blacklion.livejournal.com - Date: 2010-06-26 05:57 pm (UTC) - Expand

(no subject)

From: [identity profile] meshko.livejournal.com - Date: 2010-06-26 08:17 pm (UTC) - Expand

(no subject)

From: [identity profile] blacklion.livejournal.com - Date: 2010-06-26 05:56 pm (UTC) - Expand

(no subject)

From: [identity profile] itman.livejournal.com - Date: 2010-06-26 06:27 pm (UTC) - Expand

(no subject)

From: [identity profile] blacklion.livejournal.com - Date: 2010-06-26 06:35 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-06-26 07:04 pm (UTC) - Expand

(no subject)

From: [identity profile] blacklion.livejournal.com - Date: 2010-06-26 07:09 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-06-26 07:14 pm (UTC) - Expand

(no subject)

From: [identity profile] itman.livejournal.com - Date: 2010-06-26 07:17 pm (UTC) - Expand

(no subject)

From: [identity profile] mtyukanov.livejournal.com - Date: 2010-06-26 06:49 pm (UTC) - Expand

(no subject)

From: [identity profile] blacklion.livejournal.com - Date: 2010-06-26 06:58 pm (UTC) - Expand

(no subject)

From: [identity profile] dmarck.livejournal.com - Date: 2010-06-27 09:32 am (UTC) - Expand

(no subject)

From: (Anonymous) - Date: 2010-06-26 05:58 pm (UTC) - Expand

(no subject)

From: [identity profile] msh.livejournal.com - Date: 2010-06-26 06:21 pm (UTC) - Expand

(no subject)

From: [identity profile] itman.livejournal.com - Date: 2010-06-26 06:34 pm (UTC) - Expand

Date: 2010-06-26 06:25 pm (UTC)
From: [identity profile] renatm.livejournal.com
Сначала вообще никаких идей не было, и не был уверен, что это вообще компилируется. Решил откомпилировать, но видимо зря, потому что MSVC выдал предупреждение

warning C4244: 'argument' : conversion from 'double' to 'char', possible loss of data

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

Вообще, я считаю, что в нормальном языке программирования такое не должно компилироваться :)

Date: 2010-06-26 06:36 pm (UTC)
From: [identity profile] blacklion.livejournal.com
Вообще, я считаю, что в нормальном языке программирования такое не должно компилироваться :)
Ну да, “система типов” C/C++ ужасна, это любой хаскеллист скажет :)))

(no subject)

From: (Anonymous) - Date: 2010-06-26 09:41 pm (UTC) - Expand

(no subject)

From: [identity profile] blacklion.livejournal.com - Date: 2010-06-27 06:36 am (UTC) - Expand

...

From: [identity profile] peretyatkov.livejournal.com - Date: 2010-06-27 06:45 am (UTC) - Expand

Re: &hellip;

From: [identity profile] blacklion.livejournal.com - Date: 2010-06-27 06:47 am (UTC) - Expand

Re: &hellip;

From: [identity profile] peretyatkov.livejournal.com - Date: 2010-06-27 06:59 am (UTC) - Expand

Re: &hellip;

From: [identity profile] blacklion.livejournal.com - Date: 2010-06-27 06:55 am (UTC) - Expand

Date: 2010-06-26 06:36 pm (UTC)
From: [identity profile] itman.livejournal.com
Вообще, за неявные преобразования в Сях авторов языка нужно очень и очень ругать. Другое дело, что язык этот создавался в дремучие времена, когда не очень верили в то, что строгая типизация нужна. Да даже и сейчас я вижу много людей, которые бьют себя пяткой в грудь и кричат, что они крутые, поэтому вполне могут писать на скриптовых языках, где преобразуется вообще все во все. В Си++ хоть ограничения есть.

Date: 2010-06-26 08:11 pm (UTC)
From: [identity profile] psilogic.livejournal.com
Ну в MSVS система warning-ов вполне кошерно такие вещи отлавливает. Главное болт беречь, на варнинги его не класть.

(no subject)

From: [identity profile] itman.livejournal.com - Date: 2010-06-26 08:16 pm (UTC) - Expand

(no subject)

From: [identity profile] mtyukanov.livejournal.com - Date: 2010-06-26 08:26 pm (UTC) - Expand

(no subject)

From: [personal profile] nine_k - Date: 2010-06-26 08:46 pm (UTC) - Expand

(no subject)

From: [identity profile] itman.livejournal.com - Date: 2010-06-27 12:40 am (UTC) - Expand

(no subject)

From: [identity profile] breqwas.livejournal.com - Date: 2010-06-27 07:02 am (UTC) - Expand

(no subject)

From: [identity profile] sergeytk.livejournal.com - Date: 2010-06-27 05:54 am (UTC) - Expand

:)

Date: 2010-06-26 06:42 pm (UTC)
From: [identity profile] greps.livejournal.com
Ну да, ну да, а потом мы долго и нудно пишем языке программмирования модуль для конвертирования -
Convert.Int2Float, Convert.Ptr2Str and so on and so on...

Re: :)

Date: 2010-06-26 08:49 pm (UTC)
nine_k: A stream of colors expanding from brain (Default)
From: [personal profile] nine_k
Конверсия без потери информации — ok, хотя можно и warning выдать. И вообще, между числами — одно дело, между числом и строкой — совсем другое, imho.

Date: 2010-06-26 06:48 pm (UTC)
From: [identity profile] rogovsky.livejournal.com
Нормальный компилятор за такое должен руки поотрывать!

Date: 2010-06-26 07:52 pm (UTC)
From: [identity profile] egle.livejournal.com
+1
Tолько не отрывает, и вообще только ворнинг выдает... Я, на самом деле, не могу понять, почему он превращает эту фигню в char.

(no subject)

From: [identity profile] meshko.livejournal.com - Date: 2010-06-26 08:23 pm (UTC) - Expand

(no subject)

From: [identity profile] egle.livejournal.com - Date: 2010-06-26 07:56 pm (UTC) - Expand

Date: 2010-06-26 08:18 pm (UTC)
From: [identity profile] http://users.livejournal.com/_navi_/
Самое интересное во всей этой истории — это отутствие какой-либо вменяемой системы с предупреждениями о неявных преобразованиях в разных версиях gcc/g++: кажется, было даже так, что g++ какой-то версии на Mac OS X не выдавал предупреждение, а на Linux выдавал.

Date: 2010-06-27 08:13 am (UTC)
From: [identity profile] helvegr.livejournal.com
-Wconversion, -Wsign-conversion

(no subject)

From: [identity profile] http://users.livejournal.com/_navi_/ - Date: 2010-06-27 09:39 am (UTC) - Expand

(no subject)

From: [identity profile] helvegr.livejournal.com - Date: 2010-06-27 09:44 am (UTC) - Expand

(no subject)

From: [identity profile] moon-aka-sun.livejournal.com - Date: 2010-07-02 12:58 pm (UTC) - Expand

Date: 2010-06-26 08:18 pm (UTC)
From: [identity profile] meshko.livejournal.com
Ну тут С++ не виноват -- если есть предупреждение. У меня есть ,)

Date: 2010-06-26 08:43 pm (UTC)
From: [identity profile] lazyreader.livejournal.com
Да нет, именно C++ виноват, а вот именно компилятор (если есть предупреждение) - молодец.

(no subject)

From: [identity profile] meshko.livejournal.com - Date: 2010-06-26 08:52 pm (UTC) - Expand

(no subject)

From: [identity profile] lazyreader.livejournal.com - Date: 2010-06-26 09:16 pm (UTC) - Expand

Date: 2010-06-26 08:45 pm (UTC)
From: [identity profile] lazyreader.livejournal.com
Вообще, неявное преобразование типов - это одна из двух или трёх самых серьёзных проблем C++.
(deleted comment)

(no subject)

From: [identity profile] allambee.livejournal.com - Date: 2010-06-27 06:17 pm (UTC) - Expand

(no subject)

From: [identity profile] manpages.livejournal.com - Date: 2010-06-29 10:52 pm (UTC) - Expand

(no subject)

From: [identity profile] allambee.livejournal.com - Date: 2010-06-30 09:36 am (UTC) - Expand

Date: 2010-06-26 08:53 pm (UTC)
From: [identity profile] dimrub.livejournal.com
Не глядя. Удивлен, что это компилируется. Я бы предположил, что напечатает то, что в данной архитектуре произойдет, если из представление double взять нижний байт, и записанное там число использовать в качестве аски-кода символа (т.е. этот символ и напечатает).

Date: 2010-06-26 10:29 pm (UTC)
From: [identity profile] avva.livejournal.com
Примерно так, да. Меня тоже удивило, что компилируется, а уж то, что предупреждений не выдает... (но оказывается, это по-разному даже в разных версиях gcc, как в комментах обсуждают).

(no subject)

From: [identity profile] ilya-dogolazky.livejournal.com - Date: 2010-07-07 03:07 pm (UTC) - Expand

(no subject)

From: [identity profile] dimrub.livejournal.com - Date: 2010-07-07 03:17 pm (UTC) - Expand

(no subject)

From: [identity profile] ilya-dogolazky.livejournal.com - Date: 2010-07-07 04:00 pm (UTC) - Expand

Date: 2010-06-26 10:22 pm (UTC)
From: (Anonymous)
хорошая бага, я почти такую же недавно в продакшен коде нашел.

...

Date: 2010-06-27 06:32 am (UTC)
From: [identity profile] peretyatkov.livejournal.com
Типа данных string в С++ - нет.
Это класс расширения стандарта языка из STL.
И здесь очень часто многое прокатывает.
Хоть чего делай.
...
А потому то что напечатало - не удивился.
Впрочем даже и в отладчике не исследовал.
Вот это напечатало: m[0]=@.

Date: 2010-06-27 08:05 am (UTC)
From: [identity profile] spacediver.livejournal.com
Напечатал m[0]=@.

И почему я ожидал, что в m[0] окажется какое-нибудь строковое представление вещественного числа?.. %) Давно не программировал на сем, использовал здравый смысл.

Date: 2010-06-27 11:57 am (UTC)
From: [identity profile] wildernesscat.livejournal.com
Ничего не выдаёт ...
> ./stam.out | od -bc
0000000 155 133 060 135 075 000
          m   [   0   ]   =  \0
0000006
>

Date: 2010-06-27 12:26 pm (UTC)
From: [identity profile] zigmar.livejournal.com
Я сказал бы, что такое не откомпилируется, так как не не определен оператор присвоения для ссылки на стриг и double. Но так как явно вопрос с подвохом и код скомпилируется, то я придумал такую безумную теорию:
Какой-то из конструкторов string-а который принимает size_t или int (кажется, он инициализует пустой стринг такой длинны или резервирует данное кол-во места) почему-то не объявлен как explicit, и с помощью двойного неявного преобразования (разве такое бывает?!) double->int/size_t->string создаст пустой или длинный стринг из пробелов(?), который и поместит в map.

Date: 2010-06-27 12:30 pm (UTC)
From: [identity profile] zigmar.livejournal.com
Хмм, посмотрел документацию, вроде нету такого конструктора, чтоб один int аргумент получал.
http://www.cplusplus.com/reference/string/string/string/
http://www.sgi.com/tech/stl/basic_string.html

Пойду компилировать и смотреть. Блин, а я то думал, что неплохо в тонкостях с++ разбираюсь :)

(no subject)

From: [identity profile] zigmar.livejournal.com - Date: 2010-06-27 12:36 pm (UTC) - Expand

(no subject)

From: [identity profile] zigmar.livejournal.com - Date: 2010-06-27 12:38 pm (UTC) - Expand

(no subject)

From: [identity profile] avva.livejournal.com - Date: 2010-06-27 02:14 pm (UTC) - Expand

Date: 2010-06-27 02:36 pm (UTC)
From: [identity profile] zigmar.livejournal.com
Кстати, еще из забавных (правда безобидных) особенностей С:

int a[10];
a[4] = 1; /* ok */
4[a] = 1; /* also ok, does the same */

/* Hint: compiler interprets a[b] as *(a+b) */

Date: 2010-06-29 09:21 am (UTC)
From: [identity profile] dikij.livejournal.com
Страуструп в "The C++ Programming Language" по этому поводу пишет:
The fundamental types can be converted into each other in a bewildering number of ways. In my opinion, too many conversions are allowed.

И об'ясняет, как такой conversion (double→char) работает:
...conversion from a floating-point type to an integer type truncates. ... The behavior is undefined if the truncated value cannot be represented in the destination type. ... Conversions from integer to floating types are as mathematically correct as the hardware allows. Loss of precision occurs if an integral value cannot be represented exactly as a value of the floating type.

Date: 2010-06-29 09:22 am (UTC)
From: [identity profile] dikij.livejournal.com
Ничего хорошего в таком превращении, конечно, нет.

Date: 2010-07-01 03:03 pm (UTC)
From: [identity profile] zyama-krendel.livejournal.com
Маленький вопрос: если дело только в conversion, зачем там вся эта история с map? Просто написать что-нибудь такого типа:



будет недостаточно?

Date: 2010-07-06 07:29 am (UTC)
From: [identity profile] eoai.livejournal.com
Ну, похоже, тут проблема идет слева направо, а не наоборот, как кажется.

m[0] = d; - при исполнении выглядит как

string& x = m.operator[](0); // что само по себе очень странно
x.ctor((char)d); // пустой блок памяти вернулся, вызывается ктор

ну, а 123456.789 транформируется в 123456 = 0x0001e240, последний байт = 40 = '@'

Очередной отличный выстрел в ногу.

Date: 2010-07-06 07:31 am (UTC)
From: [identity profile] eoai.livejournal.com
Обманул, не ctor. operator=(char)

(no subject)

From: [identity profile] eoai.livejournal.com - Date: 2010-07-06 07:38 am (UTC) - Expand

December 2025

S M T W T F S
  123 4 56
78 9 10 11 1213
1415 1617181920
21 22 23 24 2526 27
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Dec. 28th, 2025 10:17 pm
Powered by Dreamwidth Studios