Кастинг константы освобождает указатель на массив указателей символа константы правильно в C

Из MSDN:

"Метод CompareTo был разработан, прежде всего, для использования в сортировке или расположении в алфавитном порядке операций. Это не должно использоваться, когда основная цель вызова метода должна определить, эквивалентны ли две строки. Чтобы определить, эквивалентны ли две строки, звоните, Равняется методу".

Они предлагают использовать .Equals вместо .CompareTo при искании только равенства. Я не уверен, существует ли различие между .Equals и == для string класс. Я буду иногда использовать .Equals или Object.ReferenceEquals вместо == для моих собственных классов в случае, если кто-то приезжает в более позднее время и переопределяет == оператор для того класса.

6
задан haccks 24 June 2014 в 18:49
поделиться

5 ответов

Несколько других указали правильный состав, но он генерирует ложное предупреждение . Это предупреждение возникает из-за возможной ошибки в стандарте C или (в зависимости от вашей интерпретации) случая, который GCC должен обрабатывать специально. Я считаю, что квалификатор const можно безопасно и однозначно поднять до типа массива. Вы можете сбросить это предупреждение с помощью -Wno-cast-qual , но, конечно же, это исключит предупреждения для случаев, которые вас действительно волнуют.

Чтобы уточнить, тип const char (*) [ 2] означает «указатель на массив (длина 2) из ​​ const char ». Массив не помечается const , только элементы массива. При сравнении с типом const void * компилятор замечает, что последний является указателем на const , тогда как первый не является, таким образом генерируя предупреждение.

6
ответ дан 8 December 2019 в 18:37
поделиться

Попробуйте:

const char (*foo)[2] = (const char (*)[2])bar();

Изменить , но если bar возвращает указатель на массив константных указателей char, как подсказывает заголовок вашего вопроса, то необходимости в приведение, если вы присвоите переменной этого типа:

char* const* foo = bar();
3
ответ дан 8 December 2019 в 18:37
поделиться

Просто примечание, вам не нужны размеры массива:

const void *bar() { 
    static const char a[10] = "abcdefghij";
    return &a[4];
}

int main() {
    const char (*foo)[2] = (const char (*)[])bar();
    return 0;
}

Так как это может быть трудно для некоторых читать:

cdecl> explain const char (*foo)[2]
declare foo as pointer to array 2 of const char
1
ответ дан 8 December 2019 в 18:37
поделиться
const char (*foo)[2] = (const char (*)[2])bar();
0
ответ дан 8 December 2019 в 18:37
поделиться

The issue with the warning in the latest version of the cast has historical roots. You know that C language (as well as C++) correctly prohibits the T** -> const T** conversion. This is correct, since allowing this conversion would open the way for some subtle violations of const-correctness rules (can be found in any self-respecting FAQ).

However, C language also prohibits T** -> const T* const* conversion. This is different from C++, which allows this conversion. (This conversion doesn't violate const-correctness.) This has been long considered a "design defect" in C language specification. This defect has been "fixed" in C++, but it continues to persist in C (even in C99). Frankly, I have no idea why it was left unchanged in C99. One of the "fallouts" of that defect (or more precisely, of that approach to treating const-correctness) is that in C language the T (*)[N] -> const T (*)[N] conversion also remains prohibited, even though it carries no inherent threats to const-correctness.

I can't reproduce the warning you are getting with my version of GCC. But if you are getting it, it appears to be just another consequence of the same ideology. If you take into account that the conversion was requested by an explicit cast operator, the GCC warning is completely unjustified. You can try to work around the warning by using a chained cast

const char (*foo)[2] = (const char (*)[2]) (void *) bar();
3
ответ дан 8 December 2019 в 18:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: