Переместить реализацию в C - PullRequest
2 голосов
/ 30 марта 2019

Я пытаюсь реализовать функцию перемещения, чтобы можно было сортировать объекты перемещения без копирования их содержимого.Вот что я имею в виду:

static void foo(const char* moved_content){
   //use moved_content
}

const char *string = //...
foo(string);
string = NULL;

Так что после того, как я передам string в foo, никто другой не сможет получить доступ к строке.Я думаю, что это облегчит отладку в случае нелегального доступа, поскольку, например, в Linux я, скорее всего, получу SEGV.

Я попробовал следующее:

static inline void* move(void **ptr){
    void *tmp = *ptr;
    *ptr = NULL;
    return tmp;
}

Но я не могуиспользуйте это как, скажем,

const char *str = "string";
const char *moved = (char*) (move((void **)&str)); //this is non-conforming

Я пытался написать макрос, используя расширение gcc, но это не похоже на способ вернуть значение из него:

#define MOVE(ptr) \
    do { \
        __typeof__(ptr) original_ptr = ptr; \
        __typeof__(*original_ptr) tmp = *original_ptr; \
        *ptr = NULL; \
    } while(0)

Есть ли способ реализоватьэто соответственно?Вероятно, _Generic - это путь ... Или явно указатель на NULL не так уж и плох?

1 Ответ

2 голосов
/ 30 марта 2019

Поскольку кажется, что вы готовы использовать расширения для языка C, ваш второй подход почти готов, просто вам нужно сделать еще один шаг вперед, сделав его " Выражением оператора "

#define MOVE_AND_CLEAN(p) ( \
  { \
    __typeof__(p) p_tmp = p; \
    p = NULL; \
    p_tmp; \
  } \
)

Используйте это так:

#include <stdio.h>

int main(void)
{
  const char * ps = "string";
  const char * pd = MOVE_AND_CLEAN(ps); 

  printf("ps = %p\npd = %p\n", (void*)ps, (void*)pd);
}

и получите:

ps = 0x0
pd = 0x123456789

: -)

...