Как отличить постоянную строку от char * в макросе C

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

Вот что я имею в виду:

void transmit(const char *data, int length);
#define tx_string(x) transmit((x), sizeof(x) -1)
void func(char *badmsg) {
  tx_string("GO");    // ok
  tx_string(badmsg);  // not OK
}

При втором вызове размер будет бессмысленным (размер указателя).

Я хочу выдать ошибку времени компиляции, если попытаюсь использовать tx_string для чего-либо, кроме строкового литерала. Это использует gcc; есть ли какая-нибудь вещь gcc, которую я могу использовать для этого?

Изменить: я работаю с буферами данных, которые могут содержать нули или не завершаться нулевыми значениями. Я ДЕЙСТВИТЕЛЬНО хочу предотвратить использование указателей для этого и предотвратить использование во время выполнения strlen () .

Редактировать 2:

Вот пример, который может вызвать проблему. Я изобрету воображаемый протокол, в котором я должен сообщить 16-битному микроконтроллеру адрес, используя команду GO, за которой следует адрес как 16-битные необработанные (два 8-битных символа), и я хочу перейти с адреса 0.

#define GOSEQ "GO\000\000"

void func(void) {
  char *bad = GOSEQ;
  tx_string(GOSEQ); // ok, sends 4 bytes: GO and two zero bytes
  tx_string(bad);   // bad, using runtime strlen sends two characters "GO"
}

Я уверен, что для этого должна быть какая-то встроенная проверка gcc. Я часто вижу исходники ядра Linux, использующие подобные уловки во время компиляции ... но не могу быстро найти конкретный.

Пока идея "Windows-программиста" выглядит неплохо, но более значимая ошибка времени компиляции будет бонусом.

9
задан Brian Tompsett - 汤莱恩 3 April 2016 в 10:05
поделиться