LINUX.ORG.RU
ФорумTalks

21 век. Язык С. Дебиан. Воскресенье.

 , ,


0

3

Драма.

1. Решил в пятницу сделать часики в lightdm.

2. Отредактировал lightdm-gtk-greeter.conf, вставил формат clock-format=%A, %d %b, %Y%n%t %H:%M:%S, полюбовался как всё функционально.

3. Суббота полёт нормальный.

4. Воскресенье еле залогинелся. Пол дня думал откуда прут глюки при логине. Под вечер смотрю, что «Воскресенье» довольно большое слово и тут в мозгу пришло понимание Ahtung - говнокодеры.

5.

lightdm-gtk-greeter-1.8.5$ vi ./src/lightdm-gtk-greeter.c

    gchar time_str[50];
    gchar *markup;

    time ( &rawtime );
    timeinfo = localtime ( &rawtime );

    strftime(time_str, 50, clock_format, timeinfo);

Найди ошибку, и получи понимание, что значат слова *** *** *** *** *** *** *** говнокодеры!.

:D

★★★★★

Ответ на: комментарий от waker

не факт. может вообще ничего в строку не писаться. зависит от реализации libc.

next_time ★★★★ ()
Ответ на: комментарий от invy

Костыли :)

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

Можно кстати в конец пробел добавлять, обнулять при успехе и юзать без &[1].

arturpub ★★ ()
Ответ на: комментарий от arturpub

Сколько либ не пишут, а все не могут завезти проверенные временем подходы.

libstdc++ и boost вполне себе проыерены временем ;)

invy ★★★★★ ()
Последнее исправление: invy (всего исправлений: 1)

А всего то и надо

boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
std::string time_str = boost::posix_time::to_simple_string(now);

CatsCantFly ()

Ну забыли они прочитать ман и проверить результат:

No more than maxsize characters will be placed into the array. If the total number of resulting characters, including the terminating NUL character, is not more than maxsize, strftime() returns the number of characters in the array, not counting the terminating NUL. Otherwise, zero is returned and the buffer contents are indeterminate.

Меня больше беспокоит магическая константа 50, которую можно и забыть поменять. Предпочитаю писать sizeof(buffer)/sizeof(buffer[0]).

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Предпочитаю писать sizeof(buffer)/sizeof(buffer[0]).

чем не нравится просто sizeof buffer?

waker ★★★★★ ()
Ответ на: комментарий от Harald

но ты конечно же заслал им уже патч вида

Это не патч, а очередной говнокод. Маны нужно иногда читать.

andreyu ★★★★★ ()
Ответ на: комментарий от Kaschenko

В сишечку так и не завезли динамические массивы?

вообще-то, завезли. уже давно. но функция strftime не позволяет узнать размер нужного буфера. поэтому придется выделять буфер с запасом, даже если пишешь на крестах.

waker ★★★★★ ()
Ответ на: комментарий от arturpub

s = realloc(s, size *= 2);

И что будет с памятью выделенной до realloc(), если реаллок не сможет выделить реаллочить память? Правильно, очередная утечка памяти.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

sizeof(buffer)/sizeof(buffer[0]).

И что это за народное творчество? Какой его смысл? Чем это лучше sizeof(buffer)/(rand()%6)

invy ★★★★★ ()
Ответ на: комментарий от andreyu

Otherwise, zero is returned and the buffer contents are indeterminate.

а, вот теперь действительно понятно в чем баг :) ну и дерьмище этот strftime...

$ find . -type f -name "*.c" | xargs grep strftime | wc -l
       0

фух.

waker ★★★★★ ()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от waker

чем не нравится просто sizeof buffer?

Тем, что вернет кол-во байт, а не элементов. Я хз, что такое gchar и я не знаю, не решит ли разработчик в следующее воскресенье заменить его на что-либо другое.

andreyu ★★★★★ ()
Ответ на: комментарий от invy

И что это за народное творчество? Какой его смысл? Чем это лучше sizeof(buffer)/(rand()%6)

Тем, что вы привели какой-то говнокод, а я подсчитал кол-во элементов вне зависимости от типа buffer.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Тем, что вернет кол-во байт, а не элементов. Я хз, что такое gchar и я не знаю, не решит ли разработчик в следующее воскресенье заменить его на что-либо другое.

можно подумать, тебе не придется переписать всю программу, если это случится. конечно же, разработчик этого сделать не решит, потому что это сломает бинарную совместимость. gchar = char. еще лучше, просто использовать char, чтобы иметь уверенность на 100%.

waker ★★★★★ ()
Ответ на: комментарий от waker

а, вот теперь действительно понятно в чем баг :) ну и дерьмище этот strftime...

Это да :)

andreyu ★★★★★ ()
Ответ на: комментарий от waker

Это простейший способ избавиться от возможных неувязок в дальнейшем. Тем более, что это константа, которую посчитает компилятор.
Но да, за кодом нужно следить.

andreyu ★★★★★ ()
Ответ на: комментарий от invy

И что это за народное творчество? Какой его смысл? Чем это лучше sizeof(buffer)/(rand()%6)

кстати да, функция strftime ожидает размер буфера в char'ах, а не в gchar'ах :)

waker ★★★★★ ()
Ответ на: комментарий от arturpub

Ее автоматически освободит strftime.

С какого перепугу он должен освобождать память, выделенную из-вне?

andreyu ★★★★★ ()
Ответ на: комментарий от arturpub

Ну вызови его с NULL да посмотри :)

Мне сложно следить за бредом, который вы называете мыслью в вашей голове.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Тем, что вы привели какой-то говнокод, а я подсчитал кол-во элементов вне зависимости от типа buffer.

теперь твоя очередь делать man strftime :)

waker ★★★★★ ()
Ответ на: комментарий от andreyu

а я подсчитал кол-во элементов вне зависимости от типа buffer.

И что тебе дает «колличество элементов»?

invy ★★★★★ ()
Ответ на: комментарий от waker

теперь твоя очередь делать man strftime :)

«No more than maxsize characters will be placed into the array.»

Что не так?

andreyu ★★★★★ ()
Ответ на: комментарий от invy

И что тебе дает «колличество элементов»?

В данном случае это как минимум не даст strftime выбраться за границы буфера, вне зависимости от типа его элементов.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Что не так?

то, что strftime не из glib, и про его gchar ничего не знает.

в понимании strftime, сharacter это или char, или utf8 codepoint (если оно поддерживается). в случае если размер gchar изменится - strftime невозможно будет использовать без изменения кода.

waker ★★★★★ ()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от andreyu

В данном случае это как минимум не даст strftime выбраться за границы буфера, вне зависимости от типа его элементов.

напиши тестовую прогу, в которой сделай typedef wchar_t gchar, вызови strftime с твоим примером вычисления размера буфера, и посмотри что будет. по-моему ты просто тупишь.

waker ★★★★★ ()
Ответ на: комментарий от h578b1bde

Это же опенсорс, проще форкнуть и сделать gchar time_str[64] переписать нормально.

... а потом поддерживать до конца своих дней, ага :)

Virtuos86 ★★★★★ ()
Ответ на: комментарий от andreyu

Строгой типизации на вас нет...

зы Сувать в функцию понимающую только char* что-то отличное от char* - стрелять себе в ногу. Делать sizeof(buffer) - стрелять в ногу, т.к. внезапно, в один прекрасный день, buffer может стать не char [], а char *. Если функция требует количества символов, то всё равно деление числа байт на размер типа тебе ничего не даст... разве что ты в utf-32 работаешь.

invy ★★★★★ ()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от waker

то, что strftime не из glib, и про его gchar ничего не знает.

Ну так это уже проблемы того, кто решил использовать gchar.

в понимании strftime, сharacter это или char, или utf8 codepoint (если оно поддерживается). в случае если размер gchar изменится - strftime невозможно будет использовать без изменения кода.

При этом strftime исправно заполнит буфер по переданному указателю. А как интерпретировать данные в этом буфере уже забота того горе-девелопера, который решился подсунуть не то, что ожидает strftime.

andreyu ★★★★★ ()
Ответ на: комментарий от waker

напиши тестовую прогу, в которой сделай typedef wchar_t gchar, вызови strftime с твоим примером вычисления размера буфера, и посмотри что будет. по-моему ты просто тупишь.

Посколько stride у strftime равен sizeof(char), то заполнен этот буфер будет как char* Какие проблемы? Пусть передавший такой буфер и разбирается с результатом.

andreyu ★★★★★ ()
Ответ на: комментарий от invy

зы Сувать в функцию понимающую только char* что-то отличное от char* - стрелять себе в ногу.

Я тут каким боком? Какое-то чудо передает некий gchar* вместо char*, а виноват я. Странная у вас логика.

Делать sizeof(buffer) - стрелять в ногу, т.к. внезапно, в один прекрасный день, buffer может стать не char [], а char *

О да, а использование магического 50 решает проблему.

Если функция требует количества символов, то всё равно деление числа байт на размер типа тебе ничего не даст...

Но ничего и не нарушит:

unsigned a[10];
char b[10];
sizeof(a)/sizeof(a[0]) == 10;
sizeof(b)/sizeof(b[0]) == 10;

При этом sizeof(a) == 40, что больше 10, переданных в strftime, а значит выход за границу буфера не произойдет. Просто заполнен этот буфер будет не так, как мог бы ожидать разработчик.

разве что ты в utf-32 работаешь.

В данном случае это ничего не даст, strftime не научится понимать stride и что-то отличное от char*

andreyu ★★★★★ ()
Ответ на: комментарий от waker

да ладно, не отмазывайся. мне пофиг.

Зачем мне отмазываться, я просто поясняю мысль, до которой вы почему-то не в состоянии дойти самостоятельно.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

О да, а использование магического 50 решает проблему.

std::string или std::vector - решают проблему.

invy ★★★★★ ()
Ответ на: комментарий от andreyu

я просто поясняю мысль, до которой вы почему-то не в состоянии дойти самостоятельно.

твоя мысль была понятна с самого начала.

waker ★★★★★ ()
Ответ на: комментарий от invy

std::string или std::vector - решают проблему.

Вы о container.size()? Да, решает. Но это c++, а не си.

andreyu ★★★★★ ()
Ответ на: комментарий от invy

И о put_time вместо strftime.

А строка в топике (./src/lightdm-gtk-greeter.c) вам о чем говорит?

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu
mv lightdm-gtk-greeter.c lightdm-gtk-greeter.cpp
sed s/gcc/g++/g Makefile > Makefile_cpp
invy ★★★★★ ()
Ответ на: комментарий от Kaschenko

В сишечку так и не завезли динамические массивы?

Нельзя - поломается совместимость со стандартом от 1812 года, который ещё Бонапарт при отступлении написал.

Napilnik ★★★★★ ()
Ответ на: комментарий от invy

mv lightdm-gtk-greeter.c lightdm-gtk-greeter.cpp
sed s/gcc/g++/g Makefile > Makefile_cpp

Отправляйте патч. Результаты давайте сюда, вместе посмеемся.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Та лучше уже форкнуть :D

На самом деле не понимаю, зачем упарываться чистым C, отказываясь от фич, которые дают плюсы... gcc вон и так уже давно c++ компайлермо собирается.

invy ★★★★★ ()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от invy

зачем упарываться чистым C, отказываясь от фич, которые дают плюсы

поговаривают, что популярная причина - это держать крестовиков подальше от проекта :)

waker ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.