- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
class fileOutBuf : public streambuf
{
public:
// ...
typedef char char_type;
typedef int int_type;
typedef int streamsize;
// ...
int printf( const char * fpFormat, ... );
inline int vprintf( const char * fpFormat, va_list fvaList )
{
if ( NULL != dpFileDescriptor )
{
if ( true == sdVerboseFlag && false == dSkipVerboseOutput)
vfprintf( dpVerboseFileDescriptor, fpFormat, fvaList );
return vfprintf( dpFileDescriptor, fpFormat, fvaList );
}
else
{
if ( NULL != dpOutputFuncPtr )
return (*dpOutputFuncPtr)( fpFormat, fvaList );
}
return 0;
}
// ....
virtual int_type overflow( int_type c = EOF );
virtual streamsize xsputn( const char_type *s, streamsize n );
// ....
};
int fileOutBuf::printf( const char * fpFormat, ... )
{
va_list lvaList;
int lRet;
va_start( lvaList, fpFormat );
if ( NULL != dpFileDescriptor )
{
if ( true == sdVerboseFlag && false == dSkipVerboseOutput)
vfprintf( dpVerboseFileDescriptor, fpFormat, lvaList );
lRet = vfprintf( dpFileDescriptor, fpFormat, lvaList );
}
else
{
if ( NULL != dpOutputFuncPtr )
lRet = (*dpOutputFuncPtr)( fpFormat, lvaList );
}
va_end( lvaList );
return lRet;
}
fileOutBuf::int_type fileOutBuf::overflow( int_type c )
{
if ( NULL != dpFileDescriptor )
{
if ( true == sdVerboseFlag && false == dSkipVerboseOutput)
fputc( c, dpVerboseFileDescriptor );
return fputc( c, dpFileDescriptor );
}
else
return fileOutBuf::printf( "%c", c );
}
fileOutBuf::streamsize fileOutBuf::xsputn( const fileOutBuf::char_type *s, fileOutBuf::streamsize n )
{
if ( NULL != dpFileDescriptor )
{
if ( true == sdVerboseFlag && false == dSkipVerboseOutput)
fwrite( s, sizeof( char_type ), n, dpVerboseFileDescriptor );
return fwrite( s, sizeof( char_type ), n, dpFileDescriptor );
}
else
return fileOutBuf::printf( "%*s", n, s );
}
нетривиальная капипаста или делаем из мухи слона.
ЗЫ после удаления всей капипасты, от класа в целом осталось что-то около 50 строк.
Это почему это?
2) v*printf не проверяет типы и число аргументов - легко уронить приложение и даже не понять почему - при этом, учитывая распространенность сишкопроблемы, g++ имеет -Wformat и ругается на аргументы printf, но не vprintf
3) под студией поддержка сишкоблядского старья никчемная (ненужно), что приводит к невозможности точного определения через vs*printf размера результирующей строки
http://ideone.com/luoI8
так устроит?
А стандарт что на эту тему говорит?
18 Language support library
18.7 Other runtime support
3. The restrictions that ISO C places on the second parameter to the va_start() macro in header
<stdarg.h> are different in this International Standard. The parameter parmN is the identifier of the
rightmost parameter in the variable parameter list of the function definition (the one just before the ...).
If the parameter parmN is declared with a function, array, or reference type, or with a type that is not com-
patible with the type that results when passing an argument for which there is no parameter, the behavior is
undefined.
SEE ALSO: ISO C subclause 4.8.1.1.
Особенно если отправил данные в v*printf
В каких случаях его все же нужно вызывать и для чего он реально служит? Да и жаль RAII тут никак не поможет...
объяснение простое - ненужно
Вызывать нужно всегда, но, имхо, в большинстве реализаций он ничего не делает, разве что записывает NULL в указатель.
Отправка данных в v*printf не освобождает от ответственности, т.к. The vprintf function does not invoke the va_end macro.
Можно ссылочку, где пишут что не нужно вызывать va_end?
Способность вести компиляторозависимую стрельбу в ноги конечно поражает.
>char tmp[1024]; // sorry if your string can be > 1023 chars - shit for msvc
А что мсвц сделает?
Только ты в коде ошибку допустил. Если стринги больше > 1023, то ноль в последний байт не запишется. Нужно было вручную его записать.
при стринге равном размеру буфера (1024) мелкомягкая реализация его заполняет целиком и возвращает 1024
это 1024 потом уйдет в конструктор std::string и всё что нужно будет на месте
А я то думал, почему у меня лаба (вроде в мсвц 6ке) не работала! У всех работало, а у меня нет. Я уж начал думать, что это я идиот. Оно и понятно, никто вокруг меня и не знал про существование ссылок...
http://ideone.com/smICJ
http://ideone.com/pLBql
http://ideone.com/jjiYN
http://ideone.com/wdfGC
вот так вот, не повезло один раз с фамилией - и ты изгой, компьютер твой лучший друг и всю жизнь за доширак тратишь на говно
а был бы Кржыжщек - воспользовался преимуществами евросоюза, исправно работал бы как все сантехником, и не тратил всю жизнь на говн... oh wait...
P.S. А вот против набросов на неодушевленные сущности (языки, софт и т.п.), и наездов на присутствующих здесь (включая меня) ничего не имею.
>языки
Вы мне конечно не поверите, но я тоже. :)
А с чего вы решили, что он питается дошираками? С чего вы решили, что он сейчас никто? Почему вы решили, что учавствование в разработки передового инновационного компилятора - это трата жизни на говно?
Это одна из самых сильных, но пока недооцененых, разработок среди языков и компиляторов. Возможностей его уровня нет ещё ни в одном языке. Даже Хаскелл стоит в стороне из-за его излишней узкоспециализированности, теоретизироанности и отсутствия важнейщих мейнстримовых возможностей.
PS: Это я вам говорю, который на языки всегда огрызается. Это что то, да значит.
может там и мультиметоды есть
Элсо, мультиметоды на .Нет языках очень просто реализуются через dynamic. Насчет dynamic в Немерле пока не знаю, возможно ещё не готов.
Элсо хватит троллить, в немерле мультиметоды легко эмулируются через паттерн матчинг.
ps: Я роман тик и ухожу в сторону заката минуса.
Знаешь, что я тебе скажу? Ты консерватор (кстати один из самых передовых и продвинутых у нас на говнокоде).
Сложно удержаться. Всё так брызжут интузиазмом, когда вещают о Nemerle, хотя лично я ничего принципиально нового не увидел. Да, изящное сочетание ООП и метапрограммирования. Да, хороший вывод типов (судя по примерам, таки лучше, чем в Scala, хоть мне и не в лом лишний раз тип указать).
Всё это уже было в лиспе 30 лет назад.
Кстати, по поводу лиспов: кто-нибудь пробовал Racket? С виду вроде годная штука, стоит вообще смотреть?
Не было, ибо там не было статической типизации. Это совсем другой уровень гигиены макросов. Ну и понятно самый передовой вывод типов на данный момент среди языков в немерле.
>Кстати, по поводу лиспов: кто-нибудь пробовал Racket?
Только его и пробовал. Сравнить с другими не могу. Мне понравилось. А именно Scheme r5rs. Элсо ракетка много диалектов лиспа из коробки поддерживает.
>вывод типов (судя по примерам, таки лучше, чем в Scala
Самый слабый вывод типов среди функциональных языков.
>Да, изящное сочетание ООП и метапрограммирования.
Так вот высокая степень метапрограммирования позволяет иметь "песочницу для игры в куличики" больше чем в С++, но без костылей. Высочайший уровень создания DSL времени компияции, например антиинъекционная типобезопасная работа с бд (не очень понятно пока не попробуешь), ФП, ООП, АОП, ЛП, чистота местами, лень, declarative query, асинхронное программирование и Computation Expressions, генератор парсеров. Притом все это не через какието костыли, а реализовано в стандартной библиотеке макросами. Притом все очень легкое в обращении, не как в с++ - ошибка в шблонах - одевай говнолазный костюм и погружайся в пучины библиотеки шаблонов для выяснения обстоятельств. Банально тебе выдадут внятное сообщение об ошибке и ты сразу исправишь. Быстрая компиляция. Интеграция на высоте. Тот же гератор парсеров - написал граматику - везде где ошибся тебе красным до компиляции подчеркнули и ты сразу поравил, подведя мышкой к крассному подчеркиванию с последующим popup сообщения. Даже типы в обработтчиках генератора граматик проверяются, что для внешних костыльных утилит обычно нонсенс (для немерле они понятно не нужны). Все типы в коде видны под мышью. Даже формошлепа есть.
потому мой текст зелёный
У меня на самом деле тоже много претензий к современным языкам. К Scala, в частности. Например, удручает скорость компиляции (maven, например, не может в fsc) и потребление памяти (тот же Haskell кушает значительно меньше памяти и компилится заметно быстрее). С IDE тоже проблемы есть.
Common Lisp - мамонт, по нагромождённости и количеству ньюансов напоминающий c++. Инфраструктура очень мутная. Если с cabal разобраться довольно просто (и пользоваться им довольно удобно), то asdf на раз вызвает баттхёрт.
Лисперы вообще мне люто доставляют. Читаю на досуге руководство к emacs, ловлю лулзы. К примеру, там есть календарь, вычисляющий лунные фазы и время восхода/захода солнца, а также экспорт дат Грегорианского календаря в календари Майя и ещё 10 других, один другого древней.
Однако путный режим нумерации строк в буфере появился относительно недавно. Опять же, визуально отображать выделения прямоугольника (Ctrl-v в vim) даже последний emacs просто не может. Можно найти плагин, но и там нужно немного геммора.
А какая система вывода типов в Хаскеле, чтобы про неё прочитать? System F? (Или я не в ту степь?)
Для функциональщины без богомерзкого ООП - самое оно.
В скале мне очень понравились примитивы/паттерны (или что это?) синхронизации и многопоточной работы. Говорят увидев их, ими даже Интел заинтересовалась.
Так о чем это я? Что-то мы отошли от темы. Conclusion: NemerleGovno.
Это ты о чём? Может, я что пропустил? Там из коробки вроде только акторы идут, stm отдельно в akka вместе с продвинутыми акторами.
См. Глава 15
Абстракции для многопоточности
http://ru.wikibooks.org/wiki/Scala_в_примерах
Не то чтобы мне сильно понравилось, но например вот это.
http://liveworkspace.org/
Поддерживает как variadic templates, так и constexpr, так и boost.
Таки я бы даже если это реализовывал, то протащил бы в буст, а потом и в стандарт.
Это будет как выглядеть?
Как то так? , как это было в boost::mpl::string?
Можно попробовать через constexpr + vt, но внутри реализации это будет выглядеть как будто влазишь на скалу без альпинистского снаряжения.
С проверкой типа во время компиляции - а оно надо? Есть же стримы.
Они плохо локализуемы, плохо читабильны, да и вообще громоздки, да и темболее не проверяют типы. А в принтфе указал ты, что нужен %d и он придет. Это как джавды два. Как говорил Тарас, с оглядкой на Аду, лишняя проверка никогда не бывает лишней.
>С проверкой типов в рантайме - совсем несложно.
Менее компиляторопереносимый велосипед через vt? Не нужен. Более переносимый уже реализован в boost::format.
>С проверкой типа во время компиляции - а оно надо?
Крестушки, как и линуксоиды, очень любят говорить: У нас нет, поэтому оно никому не нужно. Гнилая философия я вам скажу.
Это как с динамически типизированными языками. Вот почему появились статически типизированные языки? Именно чтобы не тратить время: не писать лишних тестов и избежать лишних отладок. Жаль будет, если после последней поспешно слепленной срочной заплатки что-то сработает не так у заказчика.
printf мне, как закоренелому сишнику, больше нравиться своей крткостью, естественностью, простотой и легкостью локализации.