# Warning достал !!!

**URL:** <http://linux.ru/forum/t/warning/8917>\
**Category:** Программирование: C / C++\
**Created:** [22.Декабрь.2009 06:01:19 UTC](http://linux.ru/forum/t/warning/8917 "2009-12-22T06:01:19Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![sv\_lary](http://linux.ru/forum/letter_avatar_proxy/v4/letter/s/a4c791/32.png) [@sv\_lary](http://linux.ru/forum/u/sv_lary)\
**Post date:** [22.Декабрь.2009 06:01:19 UTC](http://linux.ru/forum/t/warning/8917/1 "2009-12-22T06:01:19Z")

</div>

Есть функция, описаная как :

```
int sqlite3_prepare(...4 параметра, а это пятый : const char **pzTail /* OUT: Pointer to unused portion of zSql */);

```

Я ее вызываю следующим образом :

```
char *pzTail;rc = sqlite3_prepare(..., &pzTail);

```

Компиллятор (GCC) выдает предупреждение :

| **Цитата:** |  
|

warning: passing arg 5 of `sqlite3\_prepare’ from incompatible pointer type

|

Хоть это и warning всего, но все равно - обидно! Кто-то может объяснить, что здесь не нравится компиллятору ?

---

<div class="post-metadata">

**Author:** ![gogi](http://linux.ru/forum/letter_avatar_proxy/v4/letter/g/958977/32.png) [@gogi](http://linux.ru/forum/u/gogi)\
**Post date:** [22.Декабрь.2009 11:54:45 UTC](http://linux.ru/forum/t/warning/8917/2 "2009-12-22T11:54:45Z")

</div>

| **sv\_lary писал(а) Tue, 22 December 2009 09:01** |  
|

Есть функция, описаная как :

```
int sqlite3_prepare(...4 параметра, а это пятый : const char **pzTail /* OUT: Pointer to unused portion of zSql */);

```

Я ее вызываю следующим образом :

```
char *pzTail;rc = sqlite3_prepare(..., &pzTail);

```

Компиллятор (GCC) выдает предупреждение :

| **Цитата:** |  
|

warning: passing arg 5 of `sqlite3\_prepare’ from incompatible pointer type

|

Хоть это и warning всего, но все равно - обидно! Кто-то может объяснить, что здесь не нравится компиллятору ?

|

Если вы используете const для проверки на стадии компиляции изменения данных, то это нужно делать везде.

В вашем случае, определить перед вызовом функции.

const char \*pzTail;

показывая компилятору, что данные, на которые указывает pzTail, не должны изменяться

---

<div class="post-metadata">

**Author:** ![sv\_lary](http://linux.ru/forum/letter_avatar_proxy/v4/letter/s/a4c791/32.png) [@sv\_lary](http://linux.ru/forum/u/sv_lary)\
**Post date:** [23.Декабрь.2009 03:32:11 UTC](http://linux.ru/forum/t/warning/8917/3 "2009-12-23T03:32:11Z")

</div>

| **gogi писал(а) Tue, 22 December 2009 14:54** |  
|

В вашем случае, определить перед вызовом функции.

const char \*pzTail;

показывая компилятору, что данные, на которые указывает pzTail, не должны изменяться

|

Спасибо - помогло ! Но, честно говоря, абсолютно НЕ понятно.

Стандарт языка С. (Working Draft, 1997-11-21, WG14/N794 J11/97-158)

6.5.3 Type qualiﬁers

Syntax

type-qualiﬁer:

const

If an attempt is made to modify an object deﬁned with a const-qualiﬁed type through use of an lvalue with non-const-qualiﬁed type, the behavior is undeﬁned. If an attempt is made to refer to an object deﬁned with a volatile-qualiﬁed type through use of an lvalue with non-volatile-qualiﬁed type, the behavior is undeﬁned.98

Описание функции из библиотеки SQLite3 : pzTail is made to point to the first byte past the end of the first SQL statement in zSql.

Т.е. определение языка утверждает, что квалификатор const запрещает использовать идентификатор в качестве l-value. А в описании функции совершенно ясно говорится, что значение этого идентификатора УСТАНАВЛИВАЕТСЯ внутри функции. Т.е. он ИСПОЛЬЗУЕТСЯ в качестве l-value… И что это значит ?!

---

<div class="post-metadata">

**Author:** ![gogi](http://linux.ru/forum/letter_avatar_proxy/v4/letter/g/958977/32.png) [@gogi](http://linux.ru/forum/u/gogi)\
**Post date:** [23.Декабрь.2009 08:34:57 UTC](http://linux.ru/forum/t/warning/8917/4 "2009-12-23T08:34:57Z")

</div>

| **sv\_lary писал(а) Wed, 23 December 2009 06:32** |  
|

Т.е. определение языка утверждает, что квалификатор const запрещает использовать идентификатор в качестве l-value. А в описании функции совершенно ясно говорится, что значение этого идентификатора УСТАНАВЛИВАЕТСЯ внутри функции. Т.е. он ИСПОЛЬЗУЕТСЯ в качестве l-value… И что это значит ?!

|

const char \*\* var;

запрещает

\*\*var= ‘C’;

но разрешает

\*var= “String”;

также разрешает

s= "String;

var= &s;

Для запрета последних используется

char \* const \* var;

и

char \*\* const var;

---

<div class="post-metadata">

**Author:** ![sv\_lary](http://linux.ru/forum/letter_avatar_proxy/v4/letter/s/a4c791/32.png) [@sv\_lary](http://linux.ru/forum/u/sv_lary)\
**Post date:** [24.Декабрь.2009 03:10:16 UTC](http://linux.ru/forum/t/warning/8917/5 "2009-12-24T03:10:16Z")

</div>

Спасибо! Это надо просто выучить. Потому, что понять такое - невозможно.. Во всяком случае, после таких языков, как Pascal, Modula-2 или Ada…

---

<div class="post-metadata">

**Author:** ![gogi](http://linux.ru/forum/letter_avatar_proxy/v4/letter/g/958977/32.png) [@gogi](http://linux.ru/forum/u/gogi)\
**Post date:** [24.Декабрь.2009 05:05:14 UTC](http://linux.ru/forum/t/warning/8917/6 "2009-12-24T05:05:14Z")

</div>

| **sv\_lary писал(а) Thu, 24 December 2009 06:10** |  
|

Спасибо! Это надо просто выучить. Потому, что понять такое - невозможно.. Во всяком случае, после таких языков, как Pascal, Modula-2 или Ada…

|

Многим нравится C как раз за такие вещи (Даёшь больше звёздочек!). Другие (выросшие на ассемблере любители низкоуровневого программирования), напротив, вовсе игнорируют const и ставят уровень предупреждений такой, чтобы компилятор молчал.

А запомнить, мне кажется просто.

Есть типы char, char\*, char\*\*…

Также есть типы char const ( он же const char), char\* const, char\*\* const. Всё логично .

---

<div class="post-metadata">

**Author:** ![sv\_lary](http://linux.ru/forum/letter_avatar_proxy/v4/letter/s/a4c791/32.png) [@sv\_lary](http://linux.ru/forum/u/sv_lary)\
**Post date:** [25.Декабрь.2009 03:43:48 UTC](http://linux.ru/forum/t/warning/8917/7 "2009-12-25T03:43:48Z")

</div>

| **Цитата:** |  
|

Всё логично

|

Т.е. я эти примеры понял так :

const char \*\*\*var; // Запрещает \*\*\*var=

char \* const \*\* var; // Запрещвет \*\*var=

char \*\* const \* var; // Запрещает \*var=

char \*\*\* const var; // Запрещает var=

Или я опять ошибаюсь ?

---

<div class="post-metadata">

**Author:** ![gogi](http://linux.ru/forum/letter_avatar_proxy/v4/letter/g/958977/32.png) [@gogi](http://linux.ru/forum/u/gogi)\
**Post date:** [25.Декабрь.2009 06:19:57 UTC](http://linux.ru/forum/t/warning/8917/8 "2009-12-25T06:19:57Z")

</div>

| **sv\_lary писал(а) Fri, 25 December 2009 06:43** |  
|

| **Цитата:** |  
|

Всё логично

|

Т.е. я эти примеры понял так :

const char \*\*\*var; // Запрещает \*\*\*var=

char \* const \*\* var; // Запрещвет \*\*var=

char \*\* const \* var; // Запрещает \*var=

char \*\*\* const var; // Запрещает var=

Или я опять ошибаюсь ?

|

Это лекго проверить. )))

---

<div class="post-metadata">

**Author:** ![sv\_lary](http://linux.ru/forum/letter_avatar_proxy/v4/letter/s/a4c791/32.png) [@sv\_lary](http://linux.ru/forum/u/sv_lary)\
**Post date:** [25.Декабрь.2009 08:12:48 UTC](http://linux.ru/forum/t/warning/8917/9 "2009-12-25T08:12:48Z")

</div>

| **Цитата:** |  
|

Это лекго проверить.

|

А меня заело… Я решил - ПРОВЕРИТЬ! И написал крохотную программку. Тексты, выданные компиллятором, я вставил прямо в текст программы в виде комментариев. Характерно, что сообщения об ОШИБКАХ появились именно там. где Вы и указывали. Хотя я смысла этого по прежнему и не понимаю… Но вот три дополнительных ВАРНИНГА меня убили… Короче, смотрите сами :

```
int main(int argc, char argv[]) { char sym = '\a'; char *p_sym = &sym; char **pp_sym = &p_sym; char*** ppp_sym = &pp_sym;// 1. Запрещает ***var1= const char*** var1; var1 = ppp_sym;	// предупреждение: несовместимый тип указателя в присваивании *var1 = pp_sym;	// предупреждение: несовместимый тип указателя в присваивании **var1 = p_sym;*** var1 = sym; // ошибка: assignment of read-only location ‘ ***var1’// 2. Запрещвет** var2=char * const **var2; var2 = ppp_sym;	// предупреждение: несовместимый тип указателя в присваивании *var2 = pp_sym;** var2 = p_sym; // ошибка: assignment of read-only location ‘ **var2’*** var2 = sym;// 3. Запрещает *var3=char **const * var3; var3 = ppp_sym; *var3 = pp_sym;	// ошибка: assignment of read-only location ‘*var3’** var3 = p_sym; ***var3 = sym;// 4.Запрещает var4=char*** const var4; var4 = ppp_sym;	// ошибка: присваивание переменной ‘var4’, доступной только на чтение *var4 = pp_sym; **var4 = p_sym;*** var4 = sym;}

```

---

<div class="post-metadata">

**Author:** ![sv\_lary](http://linux.ru/forum/letter_avatar_proxy/v4/letter/s/a4c791/32.png) [@sv\_lary](http://linux.ru/forum/u/sv_lary)\
**Post date:** [25.Декабрь.2009 08:36:02 UTC](http://linux.ru/forum/t/warning/8917/10 "2009-12-25T08:36:02Z")

</div>

Этот результат был получен при использовании компиллятора :

```
$ cc --versioncc (GCC) 4.4.1 20090725 (Red Hat 4.4.1-2)Copyright © 2009 Free Software Foundation, Inc.

```

Было бы интересно узнать, что говорят другие компилляторы…

---

<div class="post-metadata">

**Author:** ![sv\_lary](http://linux.ru/forum/letter_avatar_proxy/v4/letter/s/a4c791/32.png) [@sv\_lary](http://linux.ru/forum/u/sv_lary)\
**Post date:** [25.Декабрь.2009 09:01:40 UTC](http://linux.ru/forum/t/warning/8917/11 "2009-12-25T09:01:40Z")

</div>

На Борланд-С упомянутые варнинги исчезли, но появлся свой :

```
30: Constant variable 'var4' must be initialized

```

Еще не лучше !!!

---

<div class="post-metadata">

**Author:** ![gogi](http://linux.ru/forum/letter_avatar_proxy/v4/letter/g/958977/32.png) [@gogi](http://linux.ru/forum/u/gogi)\
**Post date:** [25.Декабрь.2009 09:38:41 UTC](http://linux.ru/forum/t/warning/8917/12 "2009-12-25T09:38:41Z")

</div>

| **sv\_lary писал(а) Fri, 25 December 2009 11:12** |  
|

| **Цитата:** |  
|

Это лекго проверить.

|

А меня заело… Я решил - ПРОВЕРИТЬ! И написал крохотную программку. Тексты, выданные компиллятором, я вставил прямо в текст программы в виде комментариев. Характерно, что сообщения об ОШИБКАХ появились именно там. где Вы и указывали. Хотя я смысла этого по прежнему и не понимаю… Но вот три дополнительных ВАРНИНГА меня убили… Короче, смотрите сами :

```
int main(int argc, char argv[]) { char sym = '\a'; char *p_sym = &sym; char **pp_sym = &p_sym; char*** ppp_sym = &pp_sym;// 1. Запрещает ***var1= const char*** var1; var1 = ppp_sym;	// предупреждение: несовместимый тип указателя в присваивании *var1 = pp_sym;	// предупреждение: несовместимый тип указателя в присваивании **var1 = p_sym;*** var1 = sym; // ошибка: assignment of read-only location ‘ ***var1’// 2. Запрещвет** var2=char * const **var2; var2 = ppp_sym;	// предупреждение: несовместимый тип указателя в присваивании *var2 = pp_sym;** var2 = p_sym; // ошибка: assignment of read-only location ‘ **var2’*** var2 = sym;// 3. Запрещает *var3=char **const * var3; var3 = ppp_sym; *var3 = pp_sym;	// ошибка: assignment of read-only location ‘*var3’** var3 = p_sym; ***var3 = sym;// 4.Запрещает var4=char*** const var4; var4 = ppp_sym;	// ошибка: присваивание переменной ‘var4’, доступной только на чтение *var4 = pp_sym; **var4 = p_sym;*** var4 = sym;}

```

|

Ошибки пойманы верно. Ради этого и задумывался const.

Предупреждения связыны с тем, что в этих трех случаях нужно явно указать компилятору преобразования типа.

var1 = (char const \*\*\*)ppp\_sym; // char\*\*\* -\> char const \*\*\*

\*var1 = (char const \*\*)pp\_sym; // char\*\* -\> char const \*\*

var2 = (char \* const \*\*)ppp\_sym; // char\*\*\* -\> char \* const \*\*

Хотя мне кажется, достаточно было ограничиться предупреждениями при попытке обратного преобразования const char\* -\> char\*

Почему нет предупреждений в трех других случаях?

\*\*var1 = p\_sym; // char\* -\> char const \*

\*var2 = pp\_sym; // char\*\* -\> char \* const \*

var3 = ppp\_sym; // char\*\*\* -\> char \*\* const \*

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

Ну а в оставшихся все верно. Преобразования типа здесь не происходит.

\*\*\*var2 = sym;

\*\*var3 = p\_sym;

\*\*\*var3 = sym;

\*var4 = pp\_sym;

\*\*var4 = p\_sym;

\*\*\*var4 = sym;

Проверил на gcc (Debian 4.3.2-1.1) 4.3.2

ошибки и предупреждения в тех же местах, что и у Вас.

---

<div class="post-metadata">

**Author:** ![herfleisch](http://linux.ru/forum/letter_avatar_proxy/v4/letter/h/ecae2f/32.png) [@herfleisch](http://linux.ru/forum/u/herfleisch)\
**Post date:** [06.Июнь.2010 18:32:24 UTC](http://linux.ru/forum/t/warning/8917/13 "2010-06-06T18:32:24Z")

</div>

sv\_lary писал(а) Fri, 25 December 2009 12:01

На Борланд-С упомянутые варнинги исчезли, но появлся свой :

```
30: Constant variable 'var4' must be initialized

```

Еще не лучше !!!

Переменная должна быть инициализирована. Можно этот кусок кода, на который он ругается, посмотреть?

Скорее всего нужно всего лишь указать значение переменной при её объявлении, что-то вроде:

```
const char var4 = '\0';

```
