Предполагая, что вы не заботитесь о стиле литья компилятора и машины, есть ли заметная разница между:беззнаковое и Назад: Кастинг Указатель против Кастинг разыменовывают
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
static int64_t tosigned (void *p)
{
return *(int64_t *)p;
}
int main (void)
{
int64_t i = 0xfabf00d0badf00d;
uint64_t u = 0xabad1deacafebabe;
printf("%"PRId64 "\n" "%"PRId64 "\n", tosigned(&i), tosigned(&u));
return 0;
}
И это?
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
static int64_t tosigned (void *p, int isunsigned)
{
return isunsigned ? (int64_t)*(uint64_t *)p : *(int64_t *)p;
}
int main (void)
{
int64_t i = 0xfabf00d0badf00d;
uint64_t u = 0xabad1deacafebabe;
printf("%"PRId64 "\n" "%"PRId64 "\n", tosigned(&i, 0), tosigned(&u, 1));
return 0;
}
Ассамблея отвалов с использованием clang -S -std=c99 -Wall -Wextra
для -O2
и выше показывают никакой разницы в мощности. Тем не менее, я хотел знать, был ли более «правильный» способ сделать это, или если первый метод будет работать в неопределенном или конкретном исполнении.
Я предполагаю, что отбрасывание в одноименную строку с указателем на неподписанную версию будет таким же, как и приведение результата разыменования указателя.
фон:
я писал библиотеку int64 для Lua и наткнулся на этом академический вопрос, когда делать для арифметики преобразования типов.
Я хранил int64_t и uint64_t userdata (непрозрачные C-кадры, хранящиеся во время выполнения Lua) в стеке Lua. Есть «метаметоды», назначенные для выполнения арифметики, например, "__add"
для x + y
вместо повышения ошибки типа, потому что вы не можете (как правило) выполнять арифметику по не номерам. Однако подписанные и неподписанные значения сохраняются как разные типы и, следовательно, несовместимы. Я делаю более широкое преобразование во втором аргументе, отбрасывая его на ту же подпись, что и первая. Параметр isunsigned
примерно совпадает с «имеет ли это таблицу без знака?». Среда выполнения возвращает указатель void для сохраненного значения и то, как вы его конвертируете, зависит от вас.
Я не думаю, что есть какая-то разница, но использование функции просто для кастинга кажется излишним. – Fernando
Для библиотеки int64 для Lua см. Http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lint64, но она поддерживает только подписанные номера. OTOH, арифметика в подписанных и неподписанных одинакова, это то, как они сравниваются и печатаются по-разному. – lhf