Const przed czy const po?

Na początek prawdopodobnie wiesz, że const może być użyty do tego, aby DANE obiektu lub wskaźnik nie mogły być modyfikowane lub oba.

const Object* obj; // can't change data
Object* const obj; // can't change pointer
const Object* const obj; // can't change data or pointer

Można jednak również użyć składni:

Object const *obj; // same as const Object* obj;

Jedyną rzeczą, która wydaje się mieć znaczenie, jest to, po której stronie gwiazdki umieścisz słowo kluczowe const. Osobiście wolę umieścić const po lewej stronie typu, aby określić, że dane nie są modyfikowane, ponieważ uważam, że czyta się lepiej w moim nastawieniu od lewej do prawej, ale która składnia była pierwsza?

Więcej ważne, dlaczego istnieją dwa prawidłowe sposoby określania danych const i w jakiej sytuacji wolisz lub potrzebujesz jednego nad drugim, jeśli w ogóle?

Edit:

Wygląda na to, że była to arbitralna decyzja, kiedy standard interpretacji kompilatorów został opracowany na długo przed moimi narodzinami. Ponieważ const jest stosowane do tego, co znajduje się po lewej stronie słowa kluczowego (domyślnie?) Domyślam się, że nie było nic złego w dodaniu "skrótów" do stosowania słów kluczowych i wpisz kwalifikatory w inny sposób, przynajmniej do czasu zmiany deklaracji przez parsowanie * lub & ...

Tak było również w C, jak zakładam?

 101
Author: AJG85, 2011-03-31

6 answers

Dlaczego istnieją dwa prawidłowe sposoby określania danych {[0] } i w jakiej sytuacji wolisz lub potrzebujesz jednego nad drugim, jeśli w ogóle?

Zasadniczo, powodem, dla którego pozycja const w specyfikacjach przed gwiazdką nie ma znaczenia, jest to, że gramatyka C została zdefiniowana w ten sposób przez Kernighan i Ritchie.

Powodem, dla którego zdefiniowali gramatykę w ten sposób, było prawdopodobnie to, że ich kompilator C parsował dane wejściowe od lewej do prawej i zakończył przetwarzanie każdego / align = "left" / Użycie tokenu * zmienia stan bieżącej deklaracji na typ wskaźnika. Napotkanie const po * oznacza zastosowanie kwalifikatora const do deklaracji wskaźnika; napotkanie go przed * oznacza zastosowanie kwalifikatora do wskazywanych danych.

Ponieważ znaczenie semantyczne nie zmienia się, jeśli kwalifikator const pojawia się przed lub za specyfikatorami typu, jest on akceptowany tak czy inaczej.

Podobny przypadek powstaje przy deklarowaniu wskaźników funkcji, gdzie:

  • void * function1(void) deklaruje funkcję, która zwraca void *,

  • void (* function2)(void) deklaruje wskaźnik funkcji do funkcji, która zwraca void.

Ponownie należy zauważyć, że składnia języka obsługuje parser od lewej do prawej.

 66
Author: Heath Hunnicutt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-17 12:21:14

Reguła brzmi:

Const Jeśli po lewej nie ma nic, to odnosi się to do rzeczy prawej.

Wolę używać const po prawej stronie rzeczy, aby być const tylko dlatego, że jest to" oryginalny " sposób, w jaki const jest zdefiniowany.

Ale myślę, że jest to bardzo subiektywny punkt widzenia.

 46
Author: horstforst,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-31 16:54:03

Wolę drugą składnię. Pomaga mi śledzić' co ' jest stałe, czytając deklarację typu od prawej do lewej:

Object * const obj;        // read right-to-left:  const pointer to Object
Object const * obj;        // read right-to-left:  pointer to const Object
Object const * const obj;  // read right-to-left:  const pointer to const Object
 38
Author: Matt Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-31 17:09:42

Kolejność słów kluczowych w deklaracji nie jest taka stała. Istnieje wiele alternatyw dla "jednego prawdziwego porządku". Like this

int long const long unsigned volatile i = 0;

Czy powinno być

volatile unsigned long long int const i = 0;

??

 28
Author: Bo Persson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-31 17:14:38

Pierwszą zasadą jest użycie dowolnego formatu lokalnych standardów kodowania wymaga. Po tym: umieszczenie const z przodu nie prowadzi do końca zamieszanie podczas wpisywania, np.:

typedef int* IntPtr;
const IntPtr p1;   // same as int* const p1;

Jeśli twój standard kodowania pozwala na wpisywanie wskaźników, to naprawdę powinien nalegać na umieszczenie const po typie. W każdym przypadku, ale gdy zastosuje się do typu, const musi postępować zgodnie z tym, do czego się odnosi, więc spójność argumentuje również na korzyść const po. Ale kodowanie lokalne wytyczne przebij to wszystko; różnica zwykle nie jest ważna wystarczy, aby cofnąć się i zmienić cały istniejący kod.

 6
Author: James Kanze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-31 17:00:24

Istnieją historyczne powody, że lewa lub prawa jest akceptowalna. Stroustrup dodał const do C++ w 1983 roku, ale nie doczekał się C aż do C89/C90.

W C++ jest dobry powód, aby zawsze używać const po prawej stronie. Będziesz zawsze spójny, ponieważ funkcje składowe const muszą być zadeklarowane w ten sposób:

int getInt() const;
 5
Author: Nick Westgate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-22 23:48:05