Гарантированно ли чтение свойства X11 типа UTF8_STRING заканчивается NULL?

У меня есть следующий код:

      static Atom _NET_WM_NAME = XInternAtom( display, "_NET_WM_NAME", false );

unsigned char* wm_data = NULL;
Atom wm_type;
int wm_format;
unsigned long wm_nitems, wm_bytes;

std::string title;

int ret = XGetWindowProperty( display, window, _NET_WM_NAME, 0, 512,
    false, utf8_string, &wm_type, &wm_format, &wm_nitems, &wm_bytes, &wm_data);

if( ret == Success && wm_nitems != 0 && wm_data != NULL ) {
    title = (const char*)wm_data;  // [1]
}

Недвижимость соответствует спецификации

Итак, в моем коде выше[1]предполагает, что полученные данные всегда будут завершаться NULL. Код как есть работает, но возвращаемая сумма байтов () не включает терминатор NULL, она всегда совпадает с фактической длиной строки. Это то, что делает меня неуверенным.

Итак, мои вопросы:

  1. Гарантируется, что чтениеUTF8_STRINGСвойство всегда будет возвращать строку, ВКЛЮЧАЯ разделитель NULL?
  2. Если да, то почему терминатор NULL не включен как частьwm_nitemsсчитать?
  3. Может кто-нибудь указать, где это указано в спецификации?
  4. И, в частности, является ли приведенный выше фрагмент правильным для чтения_NET_WM_NAMEсвойство?

1 ответ

XGetWindowProperty

«XGetWindowProperty() всегда выделяет один дополнительный байт в prop_return (даже если свойство имеет нулевую длину) и устанавливает его равным нулю, чтобы простые свойства, состоящие из символов, не нужно было копировать в еще одну строку перед использованием».


wm_nitems

nitems_return: возвращает фактическое количество 8-битных, 16-битных или 32-битных элементов, хранящихся в данных prop_return.

Почему нулевой терминатор должен считаться данными. Это любезностьXGetWindowPropertyавтоматически возвращать строку с завершающим нулем (см. выше), но символ не является частью фактических данных (например, абсолютно возможно установить имя окна без окончанияnulсимвол).

Если выразиться иначе:strlenзавершающий нулевой символ также не считается, верно?


Другое дело, что строки C представляют собой массивы символов с нулевым завершением. Символ является нулевым указателем и имеет особое значение в среде C (см.: https://en.cppreference.com/w/c/types/NULL).

  • '\0'имеет типchar
  • NULLимеет типvoid*(определяется реализацией, также может быть0)
Другие вопросы по тегам