Harvester 0 May 31, 2021 Posted May 31, 2021 (edited) · Report post Столкнулся с такой странностью. В результате выполнения кода struct statfs fs; if (statfs(DREC_STORAGE_DEF, &fs) == 0) { msg(LOG_DEBUG, "f_blocks=%u\n", fs.f_blocks); msg(LOG_DEBUG, "f_bfree=%u\n", fs.f_bfree); msg(LOG_DEBUG, "f_bavail=%u\n", fs.f_bavail); size_t blocks = fs.f_blocks; size_t bfree = fs.f_bfree; size_t bavail = fs.f_bavail; msg(LOG_DEBUG, "f_blocks=%u\n", blocks); msg(LOG_DEBUG, "f_bfree=%u\n", bfree); msg(LOG_DEBUG, "f_bavail=%u\n", bavail); } получаю такой вывод: 09:47:39.949371 f_blocks=0 09:47:39.950237 f_bfree=0 09:47:39.950361 f_bavail=0 09:47:39.950421 f_blocks=103705 09:47:39.950481 f_bfree=99962 09:47:39.950540 f_bavail=99962 Т.е. при выводе непосредственно полей структуры получаем нули. Как такое может быть? Если что, функция msg() - просто обертка над printf/fprintf: void msg(int log_level, const char* mes, ...) Edited May 31, 2021 by Harvester Quote Share this post Link to post Share on other sites More sharing options...
jcxz 51 May 31, 2021 Posted May 31, 2021 · Report post 5 минут назад, Harvester сказал: Т.е. при выводе непосредственно полей структуры получаем нули. Как такое может быть? Посмотреть на результат компиляции (ассемблер) - пробовали? 5 минут назад, Harvester сказал: Если что, функция msg() - просто обертка над printf/fprintf: Видимо - кривая "обёртка"? И что такое fs - предлагаете угадывать? Quote Share this post Link to post Share on other sites More sharing options...
Harvester 0 May 31, 2021 Posted May 31, 2021 · Report post 15 minutes ago, jcxz said: Посмотреть на результат компиляции (ассемблер) - пробовали? Еще нет. Не могу понять, как сгенерировать листинг :( 24 minutes ago, jcxz said: Видимо - кривая "обёртка"? void msg(int log_level, const char* mes, ...) { va_list arg; struct timeval tv; struct tm* tm = NULL; if (log_level > logLevelMax) return; gettimeofday(&tv, NULL); tm = localtime(&tv.tv_sec); fprintf(_file4log, "%02u:%02u:%02u.%06lu ", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec); va_start(arg, mes); vfprintf(_file4log, mes, arg); va_end(arg); } Что тут может быть кривого? 26 minutes ago, jcxz said: И что такое fs - предлагаете угадывать? Просто структура. Обновил код. Quote Share this post Link to post Share on other sites More sharing options...
xvr 4 May 31, 2021 Posted May 31, 2021 · Report post Прототип msg в месте вызова виден? Quote Share this post Link to post Share on other sites More sharing options...
Harvester 0 May 31, 2021 Posted May 31, 2021 · Report post 1 hour ago, xvr said: Прототип msg в месте вызова виден? Да Получил ассемблерный листинг. addi 0,31,152 # tmp235,, lis 9,.[email protected] # tmp236, la 3,.[email protected](9) #,, tmp236 mr 4,0 #, tmp235 bl statfs64 # mr 0,3 # D.6778, cmpwi 7,0,0 #, tmp237, D.6778 bne 7,.L48 # .LBB9: .loc 2 382 0 lwz 9,160(31) # fs.f_blocks, D.6781 r9 <- fs.f_blocks.hi lwz 10,164(31) # fs.f_blocks, D.6781 r10 <- fs.f_blocks.lo li 3,10 #, r3 <- LOG_DEBUG lis 0,.[email protected] # tmp238, addic 4,0,.[email protected] #, tmp238, r4 <- адрес строки mr 5,9 #, D.6781 r5 <- r9 (fs.f_blocks.hi) mr 6,10 # tmp5, D.6781 r6 <- r10 (fs.f_blocks.lo) crxor 6,6,6 r6 <- 0 bl msg # msg() .loc 2 385 0 lwz 9,160(31) # fs.f_blocks, D.6782 r9 <- fs.f_blocks.hi lwz 10,164(31) # fs.f_blocks, D.6782 r10 <- fs.f_blocks.lo stw 10,12(31) # blocks, D.6782 12(31) <- r10 (blocks = fs.f_blocks.lo) .loc 2 388 0 li 3,10 #, r3 <- LOG_DEBUG lis 0,.[email protected] # tmp239, addic 4,0,.[email protected] #, tmp239, r4 <- адрес строки lwz 5,12(31) # blocks, r5 <- 12(31) (blocks) crxor 6,6,6 r6 <- 0 bl msg # msg() .L48: Получается, что а) поля структуры fs 64-битные и б) VA_ARGS некорректно работает с 64-битными значениями Чуда в очередной раз не произошло :D Quote Share this post Link to post Share on other sites More sharing options...
Сергей Борщ 46 May 31, 2021 Posted May 31, 2021 · Report post 19 минут назад, Harvester сказал: и б) VA_ARGS некорректно работает с 64-битными значениями Ну хорошо хоть не Петров с Бошировым виноватыми назначены. 6 часов назад, Harvester сказал: msg(LOG_DEBUG, "f_bfree=%u\n", fs.f_bfree); Позволю себе поинтересоваться, а переменную какого типа вы тут просили напечатать (%u)? Quote Share this post Link to post Share on other sites More sharing options...
Harvester 0 May 31, 2021 Posted May 31, 2021 · Report post 10 minutes ago, Сергей Борщ said: Позволю себе поинтересоваться, а переменную какого типа вы тут просили напечатать (%u)? А слона-то я и не заметил )))) Замена модификатора на %llu решило проблему. Пункт б) вычеркиваем - сам дурак. Приношу извинения разработчикам компилятора и, на всякий случай, Петрову с Бошировым. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 51 May 31, 2021 Posted May 31, 2021 · Report post 59 минут назад, Harvester сказал: Получается, что а) поля структуры fs 64-битные и б) VA_ARGS некорректно работает с 64-битными значениями Поэтому я и спрашивал "что такое fs?" То же самое касается и всех прочих структур и функций, которые вы выкладываете. Думаете тут форум ясновидящих, умеющих угадывать что там внутри вы понаписали? Quote Share this post Link to post Share on other sites More sharing options...
Harvester 0 June 1, 2021 Posted June 1, 2021 · Report post 14 hours ago, Сергей Борщ said: Позволю себе поинтересоваться, а переменную какого типа вы тут просили напечатать (%u)? И все равно непонятно. Пусть у меня переменная uint64_t. Почему же модификатор %u выводит 0, хотя значение, содержащееся в переменной, укладывается в диапазон uint32_t? Quote Share this post Link to post Share on other sites More sharing options...
Сергей Борщ 46 June 1, 2021 Posted June 1, 2021 · Report post 1 час назад, Harvester сказал: Почему же модификатор %u выводит 0, хотя значение, содержащееся в переменной, укладывается в диапазон uint32_t? Я ожидал этого вопроса (точнее, он у меня тоже вчера возник). Думаю, это происходит потому, что параметры передаются через стек. Процессор у вас с маленькими индейцами, на стек кладется сначала младшее слово, потом старшее (в котором нули). При выводе со стека берется и выводится верхнее слово (с нулями). Можно предположить, что если бы вы выводили два значения за один вызов printf() - вы увидели бы вместо первого числа ноль, вместо второго - значение младшего слова первой переменной. 15 часов назад, Harvester сказал: Замена модификатора на %llu решило проблему В <inttypes.h> есть специальные определения PRIu64 для вывода 64-битных значений. Их использование предпочтительно, если один и тот же исходник предполагается компилировать для разных платформ или разными компиляторами. Не у каждого компилятора для вывода 64-битных значений будет использоваться "%llu", а в этом файле PRIu64 будет содержать подходящее для данного компилятора определения. Строка будет выглядеть так: msg(LOG_DEBUG, "f_blocks=" PRIu64 "\n", fs.f_blocks); Quote Share this post Link to post Share on other sites More sharing options...
jcxz 51 June 1, 2021 Posted June 1, 2021 · Report post 2 часа назад, Harvester сказал: Пусть у меня переменная uint64_t. Почему же модификатор %u выводит 0, хотя значение, содержащееся в переменной, укладывается в диапазон uint32_t? Потому что в форматной строке printf()-у вы сообщаете, что передадите ему 4 слова, а передаёте больше. И какой из передаваемых аргументов куда попадёт - зависит от размерностей аргументов и от порядка записи аргументов в стек (от начала к концу или наоборот). Quote Share this post Link to post Share on other sites More sharing options...