Czy lepiej usunąć "const"przed" prymitywnymi " typami używanymi jako parametry funkcji w nagłówku?

W procesie weryfikacji kodu, jeden z moich współpracowników wspomniał mi, że "const" przed " prymitywnymi typami "używanymi jako parametr funkcji w nagłówku jest bez znaczenia i zalecił usunięcie tych"const". zasugerował użycie" const " tylko w pliku źródłowym w takich przypadkach. Typy prymitywne oznaczają typy takie jak "int"," char"," float " itp.

Oto przykład.

Przykład.h

int ProcessScore(const int score);

Example.cc

int ProcessScore(const int score) {
  // Do some calculation using score
  return some_value;
}

Jego sugestia robi jak follows:

Przykład.h

int ProcessScore(int score);  // const is removed here.

Example.cc

int ProcessScore(const int score) {
  // Do some calculation using score
  return some_value;
}
Ale jestem trochę zdezorientowany. Zwykle użytkownik będzie patrzył tylko na nagłówek, więc jeśli występuje niezgodność między nagłówkiem a plikiem źródłowym, może to spowodować zamieszanie. Czy ktoś mógłby mi coś doradzić?
Author: chanwcom, 2017-09-19

5 answers

Dla wszystkich typów (nie tylko pierwotnych), kwalifikatory najwyższego poziomu const w deklaracji funkcji są ignorowane. Tak więc następujące cztery wszystkie deklarują tę samą funkcję:

void foo(int const i, int const j);
void foo(int i, int const j);
void foo(int const i, int j);
void foo(int i, int j);

Kwalifikator const nie jest jednak ignorowany wewnątrz funkcji Ciała . Tam może mieć wpływ na konsystencję. Ale to jest szczegół implementacji funkcji. Więc ogólny konsensus jest taki:

  1. Zostaw const z deklaracji. To tylko bałaganu i nie wpływa na sposób, w jaki klienci będą wywoływać funkcję.

  2. Pozostaw const w definicji , Jeśli chcesz, aby kompilator wychwycił przypadkową modyfikację parametru.

 67
Author: StoryTeller,
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
2017-09-19 06:35:42

Parametr funkcji deklarowany const i bez const jest taki sam, gdy dochodzi do rozdzielczości przeciążenia. Więc na przykład funkcje

void f(int);
void f(const int);

Są takie same i nie mogą być zdefiniowane razem. W rezultacie lepiej nie używać const w deklaracji dla parametrów, aby uniknąć powielania. (Nie mówię o const reference lub const pointer - ponieważ modyfikator const nie jest najwyższym poziomem.)

Oto dokładny cytat ze standardu.

Po wyprodukowaniu lista z typów parametrów, wszelkie kwalifikatory najwyższego poziomu modyfikujące typ parametru są usuwane podczas tworzenia typ funkcji. Wynikowa lista przekształconych typów parametrów oraz obecność lub brak elipsy lub pakiet parametrów funkcji jest listą typów parametrów funkcji. [Uwaga: transformacja ta nie wpływa na typy parametrów. Na przykład, int(*)(const int p, decltype(p)*) i int(*)(int, const int*) są identycznymi typami. - Uwaga końcowa]

Użyteczność const w definicji funkcji jest dyskusyjne-rozumowanie za tym jest takie samo jak używanie const do deklarowania zmiennej lokalnej - pokazuje innym programistom czytającym Kod, że ta wartość nie będzie modyfikowana wewnątrz funkcji.

 40
Author: Artemy Vysotsky,
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
2017-09-20 05:48:58

Postępuj zgodnie z zaleceniami podanymi w code review.

Użycie const dla argumentów wartości nie ma wartości semantycznej - jest tylko znaczące (potencjalnie) dla implementacji twojej funkcji - i nawet w takim przypadku argumentowałbym, że jest niepotrzebne.

Edytuj: Dla jasności: prototypem twojej funkcji jest publiczny interfejs do twojej funkcji. const daje gwarancję, że nie będziesz modyfikował referencji.

int a = 7;
do_something( a );

void do_something(       int& x );  // 'a' may be modified
void do_something( const int& x );  // I will not modify 'a'
void do_something(       int  x );  // no one cares what happens to x

Używanie const jest czymś podobnym do TMI - nie ma znaczenia gdziekolwiek poza wewnątrz funkcji, czy 'x' jest modyfikowany.

Edit2: bardzo podoba mi się również Informacja w odpowiedź gawędziarza

 15
Author: Dúthomhas,
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
2017-09-19 05:49:25

Jak wiele innych osób odpowiedziało, z punktu widzenia API, wszystkie poniższe są równoważne i są równe dla rozdzielczości przeciążenia:

void foo( int );
void foo( const int );
[[18]}ale lepszym pytaniem jest to, czy dostarcza to jakiegokolwiek znaczenia semantycznego konsumentowi tego API, czy też zapewnia egzekwowanie dobrych zachowań od programisty implementacji.

Bez dobrze zdefiniowanych wytycznych programistycznych, które wyraźnie to definiują, const argumenty skalarne nie mają łatwo oczywistego znaczenia semantycznego .

Od konsumenta: const int nie zmienia danych wejściowych. Może to być literał, lub może być z innej zmiennej (zarówno const, jak i non-const)

Od dewelopera: const int nakłada ograniczenie na lokalną kopię zmiennej (w tym przypadku argumentu funkcji). Oznacza to tylko zmodyfikowanie argumentu, pobranie kolejnej kopii zmiennej i zmodyfikowanie jej zamiast tego.

Podczas wywoływania funkcji, która przyjmuje argument po wartości, kopia tego argumentu jest tworzona na stosie dla wywołanej funkcji. To daje funkcji lokalną kopię argumentu dla całego jej zakresu, który może być następnie modyfikowany, używany do obliczeń, itd -- bez wpływu na oryginalne dane wejściowe przekazane do wywołania. Efektywnie, dostarcza ona lokalnego argumentu zmiennej wejściowej.

Oznaczając argument jako const, oznacza to po prostu, że ta kopia nie może być modified; ale to nie zabroni deweloperowi kopiowania i wprowadzania modyfikacji do tej kopii. Ponieważ od początku była to kopia, nie wymusza ona aż tak wiele z wnętrza implementacji - i ostatecznie nie robi wielkiej różnicy z punktu widzenia konsumenta.

Jest to przeciwieństwo przechodzenia przez odniesienie , w którym odniesienie do int& jest semantycznie różne od const int&. Ten pierwszy jest w stanie mutować swój wkład; ten drugi jest możliwe jest jedynie obserwowanie wejścia (pod warunkiem, że implementacja nie usunie const_cast const-Ness -- ale zignoruje tę możliwość); w ten sposób, const-Ness na odniesienia mają implikowane znaczenie semantyczne.

[18]} nie przynosi większych korzyści będąc w publicznym API; i (imo) wprowadza niepotrzebne ograniczenia do wdrożenia. Jako dowolny, wymyślony przykład -- prosta funkcja jak:
void do_n_times( int n )
{
   while( n-- > 0 ) {
       // do something n times
   } 
}

Teraz trzeba by napisać za pomocą niepotrzebnego Kopia:

void do_n_times( const int n )
{
    auto n_copy = n;
    while( n_copy-- > 0 ) {
        // do something n times
    }
}

Niezależnie od tego, czy Skalary const są używane w publicznym API, jedną z kluczowych rzeczy jest to, aby były zgodne z projektem. Jeśli API losowo przełącza się między argumentami skalarnymi const a argumentami nie-const, może to spowodować zamieszanie co do tego, czy ma być jakieś dorozumiane znaczenie dla konsumenta.

TL; DR: const typy skalarne w publicznym API nie przekazują znaczenia semantycznego, chyba że są wyraźnie zdefiniowane przez własne wytyczne dla Twoja domena.

 7
Author: Bitwize,
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
2017-09-19 21:03:22

I myślałem że const jest wskazówką dla kompilatora, że niektóre wyrażenia nie zmieniają się i odpowiednio optymalizują. Na przykład sprawdzałem, czy liczba jest pierwsza, szukając dzielników do pierwiastka kwadratowego Liczby i myślałem, że zadeklarowanie argumentu const zajęłoby sqrt(n) poza pętlą for, ale tak się nie stało.

To może nie być konieczne w nagłówku, ale z drugiej strony, można powiedzieć, że wszystko, czego potrzebujesz, to nie modyfikować argumentu i nigdy konieczne. Wolałbym zobaczyć const gdzie jest const, nie tylko w źródle, ale także w nagłówku. Niespójności między deklaracją a definicją sprawiają, że jestem ostrożna. To tylko moje zdanie.

 -2
Author: Lio,
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
2017-09-19 18:53:02