Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

pragma once vs guards

Ostatnio zmodyfikowano 2016-04-09 00:21
Autor Wiadomość
mokrowski
Temat założony przez niniejszego użytkownika
pragma once vs guards
» 2016-04-08 22:37:28
Na wstępie zaznaczę że nie chodzi o żaden flame war a o rzetelną dyskusję. Jeśli nie w tym dziale, proszę o przeniesienie...

Z racji tego że zamknięto temat gdzie pragma była zagadnieniem, chcę zapytać @Alueril'a czy może wskazać _praktyczny_rzeczywisty_projekt_ w którym napotkał sytuację wiązania linkami twardymi plików i gdzie pragma sobie nie poradziła? Zgadzam się z jednym. Zaznaczam że nie chodzi o typowe legacy... i utrzymanie/rozwijanie starego kodu.
Zawsze da się pokazać sytuację w której dana technika nie działa i ma problemy. Z makrami jest tak samo.

Osobiście dla mnie wadą ogromną makr wartowniczych jest:
1. Zaśmiecanie 1 i trudnej w kontroli przestrzeni nazewniczej
2. Nakładanie się przestrzeni nazewniczych w bibliotekach (zawsze znajdzie się taki który wybierze nazwę a ja w nią "wdepnę" :-/)
3. Stosowanie "nie-języka" czyli automatu który nie ma pojęcia co i jak składa (a składa pliki).

Oczywiście znam zastosowanie gdzie makra wartownicze bronią się i owszem, myślę że warto stosować. Sytuacja gdzie jest z włączanych bardzo dużo nagłówków a pierwotnie było 1 makro wartownicze. Dodanie obecności sprawdzania tegoż istotnie redukuje czas kompilacji.

Poza tym:
C/C++
cd / opt / local / include / boost; grep - R "pragma once" * | wc - l
2808

Widać więc że i twórcy boost'a stosują

Uściślając co do return 0 z w C to ściśle od wersji 99 można nie stosować :-) Czyli ogólnie _nie_stosować_ :-)
P-147081
Rashmistrz
» 2016-04-08 23:01:01
Co do tekstów z konsoli to stosuj [log] ... [/log], a nie [cpp] ... [/cpp].

cd / opt / local / include / boost; grep - R "pragma once" * | wc - l
2808

Po co te podłogi? :D :
_praktyczny_rzeczywisty_projekt_
_nie_stosować_
P-147083
Kaikso
» 2016-04-08 23:31:24
Błąd przy dowiązaniach twardych?

test.hpp
C/C++
#pragma once
#include <iostream>

static inline void test()
{
    std::cout << "test" << std::endl;
}

test.cpp
C/C++
#include "test.hpp"
#include "test.hl.hpp"

int main()
{
    test();
    return 0;
}

ln test.hpp test.hl.hpp
ls -li
razem 12
4719222 -rw-rw-r-- 1 andrzej andrzej  85 kwi  8 23:27 test.cpp
4718657 -rw-rw-r-- 2 andrzej andrzej 102 kwi  8 23:24 test.hl.hpp
4718657 -rw-rw-r-- 2 andrzej andrzej 102 kwi  8 23:24 test.hpp
g++ test.cpp -o test
./test
test

U mnie działa :P
P-147084
Elaine
» 2016-04-09 00:21:15
czy może wskazać _praktyczny_rzeczywisty_projekt_ w którym napotkał sytuację wiązania linkami twardymi plików i gdzie pragma sobie nie poradziła?
Zacytuję swój post:
W praktyce kompilatory przybliżają to porównując numer urządzenia i iwęzła
Czym charakteryzują się hardlinki? Tym, że na danym systemie plików dwie różne nazwy odnoszą się do tego samego iwęzła, więc para (dev, ino) dla dwóch hardlinków będzie taka sama.

W rzeczywistości większym problemem są wszelkie sytuacje, gdzie dwa różne systemy plików według kernela są jednym systemem plików. Gdy któryś raz z rzędu zdarzyło mi się spowodować "redefinicje" (i to dość wredne, bo np. spod IDE działało, ale kompilacja z palca już nie), bo nagłówek był na dysku lokalnym, który jednocześnie był eksportowany po sieci i zamontowany (żeby mieć tą samą ścieżkę na wszystkich komputerach i nie musieć pamiętać, na którym pracuję) to stwierdziłem, że mam dość #pragma once.

1. Zaśmiecanie 1 i trudnej w kontroli przestrzeni nazewniczej
2. Nakładanie się przestrzeni nazewniczych w bibliotekach (zawsze znajdzie się taki który wybierze nazwę a ja w nią "wdepnę" :-/)
Więc zamiast wymyślać nazwy, generuj je. Jeśli nazwa makra jest tworzona z UUIDu, to te problemy przestają być problemami (chyba że na codzień stykasz się z kodem, który używa identyfikatorów w rodzaju INCLUDED_FB6A84BB6FEB48C6B30886391376FE07, ale wtedy współczuję).

Widać więc że i twórcy boost'a stosują
Tylko, jeśli kompilator obsługuje (patrz BOOST_HAS_PRAGMA_ONCE) i głównie po to, by kompilatory, które implementują #pragma once, a nie rozpoznają makr wartowniczych (czyli kompilator Microsoftu, są jakieś inne?), były w stanie pominąć ponowne odczytywanie pliku.

Ponieważ jednak boost stara się wspierać również Solaris Studio, które w ogóle nie obsługuje #pragma once, to boost używa przede wszystkim makr wartowniczych.

Swoją drogą:
>> find /usr/include/boost/ -name '*.hpp' | wc -l
10215
>> grep -c "#[[:space:]]*pragma once" /usr/include/boost/**/*.hpp | cut -d':' -f2 | grep -c '^[^0]'
2502
Tylko ćwierć plików używa #pragma once.
P-147085
« 1 »
  Strona 1 z 1