Назначение при возврате значения - PullRequest
0 голосов
/ 30 января 2019

Я не понимаю функцию, используемую моим коллегой.Он не может. Он использует странные блоки возврата.

block_t *get_block(void *p)
{
    char *tmp;
    tmp = p;
    return (p = tmp -= 16);
}

Он говорит, что он должен вернуть форму и адрес.

Нужна помощь, чтобы понять возвращение!Большое спасибо:)

Ответы [ 3 ]

0 голосов
/ 30 января 2019

Ничего особенного в return нет.Это просто выражение, как и в любом другом месте.

Вы можете переписать его следующим образом:

block_t *get_block(void *p)
{
    char *tmp = p;
    p = tmp - 16;
    return p;
}

или

block_t *get_block(void *p)
{
    char *tmp = p;
    tmp -= 16;
    p = tmp;
    return p;
}

или

block_t *get_block(void *p)
{
    char *tmp = p;
    tmp -= 16;
    return (block_t *)tmp;
}

Присвоение в операторе return не оказывает никакого влияния после возврата из этой функции.

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

0 голосов
/ 30 января 2019

Это очень просто, но очень некорректно, не переносимо и подвержено ошибкам.

Он берет адрес на 16 символов раньше и возвращает его.Он должен сделать арифметику указателя на указатель на символ, поэтому он должен сделать его символом.Второе назначение не нужно

0 голосов
/ 30 января 2019

Все операторы C вычисляют значения (кроме оператора приведения с void в качестве целевого типа или вызова функции, возвращающей void).В частности, операции присваивания и оп / присваивания оцениваются по присвоенному значению.Следовательно, это утверждение:

    return (p = tmp -= 16);

эквивалентно

    tmp -= 16;
    p = tmp;
    return p;

И последнее точно так же, как I будет писатьэто если это то, что я хотел сделать.Сжатие всего этого в одном выражении усложняет чтение и понимание кода человеком и не дает никаких компенсирующих преимуществ.

ОДНАКО, ваш конкретный случай еще хуже.В вашем случае p и tmp являются локальными переменными функции, поэтому их присвоение не влияет на вызывающую функцию.Поэтому нет смысла присваивать новое значение p, если оно не будет впоследствии считываться (с p).Это может отражать или не отражать ошибку программирования.Если реальное поведение функции корректно как есть, тогда я написал бы всю функцию совсем по-другому:

block_t *get_block(void *p) {
    return (block_t *) (((char *) p) - 16);
}
...