Zarówno GCC, oraz inne kompilatory, jak i same standardy języków C/C++, przewidują pewne rozszerzenia języka, które zazwyczaj adresują jakiś problem, bądź też dodają nową funkcjonalność. Tych rozszerzeń jest masa - w zasadzie każdy popularny kompilator ma niemałą listę takich dodatków, i oczywiście nie zamierzam ich wszystkich opisywać w tym poście. Wspomnę natomiast o dwóch: atrybucie init_priority dla globalnych inicjacji obiektów w GCC C++, oraz znaku dolara ($) w nazwach zmiennych - rozszerzeniu pojawiającym się w różnych miejscach. Przy okazji tego ostatniego, zaprezentuje jedno zadanie z tegorocznego testu na Technika Informatyka (który od dwóch dni krąży po sieci).

init_priority


Przeglądając listę extensionów do GCC można się natknąć na atrybut init_priority (patrz 7.7 C++-Specific Variable, Function, and Type Attributes), który adresuje problem kolejności inicjacji obiektów globalnych w C++ (problem, o którym pisał niedawno Xion).

Problem polega na tym, że jeżeli mamy w projekcie tylko jeden plik .cpp z globalnymi obiektami, np:
MojaKlasa A;
MojaKlasa B;

To sprawa jest łatwa - najpierw zostanie zainicjowany (a więc zostanie wywołany konstruktor) obiektu A, a potem obiektu B.
Alee.... jeżeli mamy kilka plików, w których w jednym w powyższy sposób deklarujemy obiekty A i B, a w innym C i D, to niestety nie mamy pewności jaka będzie kolejność wywołań konstruktorów tychże obiektów. W zasadzie są w tym wypadku tylko dwie możliwości:
Możliwość 1: A B C D
Możliwość 2: C D A B
Zakłada się więc, że kolejność inicjalizacji takich obiektów jest przypadkowa, niesprecyzowana i nie dająca się przewidzieć.

Dodam również, że jest to jeden z błędów w miarę często robionych przez programistów C++ (przyznaje się, że parę razy również się na to złapałem ;>).

I tutaj wchodzi init_priority. W skrócie - możemy nadać priorytety inicjalizacji obiektom, globalnie względem projektu. Priorytet w tym wypadku jest wartością od 65535 (najmniejszy) do 101 (najszybciej inicjowane) włącznie. Domyślnym priorytetem (tj. bez zdefiniowanego atrybutu init_priority, jest 65535).

W kodzie wygląda to nastepująco:
Plik 1.cpp
MojaKlasa A __attribute__ ((init_priority (1001)));
MojaKlasa B __attribute__ ((init_priority (1000)));


Plik 2.cpp
MojaKlasa C;
MojaKlasa D;

W tym wypadku kolejność wywoływania obiektów jest znana, i zawsze pozostanie taka sama: B A C D;

Warto zaznaczyć, że jeżeli obiekt ma konstruktor z parametrem, to parametr ten podaje się po atrybucie (tak dziwnie jakoś):
MojaKlasa A __attribute__ ((init_priority (1001))) ("parametr konstruktora", 2, 3, 4);
Szczerze to sobie po prostu makro na to zrobiłem (dużo wygodniejsze niż pisać to całe __atrijużmisueznudziłopisanie):
#define INIT_PRIO(a) __attribute__ ((init_priority (a)))

Oczywiście, jeżeli kilka obiektów w różnych plikach ma ten sam priorytet, to, w obrębie własnej grupy, nadal ich kolejność inicjalizacji nie jest przewidywalna.

Niestety, jak większość rozszerzeń kompilatorów, powyższe dostępne jest jedynie dla kompilatora o którym mówię, czyli GCC. Jeżeli kojarzysz podobne rozwiązanie w innym kompilatorze, zachęcam do wspomnienia o nim w komentarzu :)


Dolar w nazwie zmiennej


Zacznę od screenshota z krążącego po sieci testu teoretycznego na Technika Informatyka sprzed paru dni:

Zadanie 9.
(pomińmy brak średnika w 3ciej linii - to jakiś błąd skanu pewnie)

Narzucającą się odpowiedzią na powyższe pytanie jest odpowiedź C. PHP - każdy kto widział PHP na oczy wie, że nazwy zmiennych rozpoczynają się tam od dolara, i mogę się domyślić, że taka jest też prawidłowa odpowiedź na to pytanie.

W rzeczywistości natomiast, odpowiedzi B, C oraz D są prawidłowe :)

Zacznijmy od języka Java. W trzecim rozdziale książki The Java Language Specification, a konkretniej w paragrafie 3.8 Identifiers możemy znaleźć następujące informacje:
An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter.
[...]
The Java letters include uppercase and lowercase ASCII Latin letters A-Z  (\u0041-\u005a), and a-z  (\u0061-\u007a), and, for historical reasons, the ASCII underscore (_, or \u005f) and dollar sign ($, or \u0024). The $  character should be used only in mechanically generated source code or, rarely, to access preexisting names on legacy systems.

W wolnym tłumaczeniu - identyfikatory (nazwy zmiennych, funkcji, etc) w Javie muszą zaczynać się od "Liter Java", do których zalicza się m.in. znak dolara. Co prawda zaznaczone jest, że jest on tam w celach zapewnienia wstecznej kompatybilności i że sugeruje się używanie go jedynie w generatorach kodu, ale nie zmienia to faktu, iż kod z obrazka jest poprawnym fragmentem kodu Java. Czyli odpowiedź D również jest prawidłowa.

Jeśli zaś chodzi o odpowiedź B, czyli języki C/C++, to posłużę się dwoma cytatami.
Pierwszy pochodzi z, cytowanej już wcześniej, dokumentacji GCC:

4.26 Dollar Signs in Identifier Names

In GNU C, you may normally use dollar signs in identifier names. This is because many traditional C implementations allow such identifiers. However, dollar signs in identifiers are not supported on a few target machines, typically because the target assembler does not allow them.

W wolnym tłumaczeniu: znak dolara jest dozwolony na większości architektur, ponieważ większość implementacji C go obsługuje (taki trochę reverse-extension ;p), oprócz architektur w których w assemblerze (bo gcc/g++ kompilują do assemblera) nie można używać znaku $ w identyfikatorach.

Drugi cytat pochodzi ze standardu języka C99 (a konkretniej z draftu numer n1336) z sekcji Common extensions:
J.5.2 Specialized identifiers
Characters other than the underscore _,letters, and digits, that are not part of the basic
source character set (such as the dollar sign $,orcharacters in national character sets)
may appear in an identifier (6.4.2).

Czyli, w wolnym tłumaczeniu: niektóre niestandardowe znaki, takie jak np. znak dolara, mogą występować w identyfikatorach.

Do powyższych cytatów dorzucę, że wg moich testów, $ na początku zmiennej kompiluje się zarówno w GCC (gcc/g++) jak i w MS C/C++ Compiler (używanym m.in. w pakiecie Visual C++).

Tak więc można spokojnie uznać, że kod z obrazka jest również prawidłowy w C/C++, a więc odpowiedź B jest również prawidłowa.

Podsumowując, jak pisałem wcześniej, odpowiedzi B, C oraz D są w tym zadaniu prawidłowe, Q.E.D. :)


Na koniec ciekawostka! Jeżeli zastanawiacie się, czy zdalibyście test na Technika Informatyka, to zachęcam do zmierzenia się z poniższym pytaniem :)))

Taaa... to jest DVI :P

I tyle :)

Comments:

2010-06-23 10:30:06 = dr_bonzo
{
Ostatnie pytanie to odp: "E" - "Eeeee, nie wiem"

Masakra z tymi pytaniami
}
2010-06-23 10:39:21 = Mariusz Kędziora
{
No z tymi dolarami w nazwie zmiennej też pewnie z marszu bym powiedział, że to PHP. Dobrze wiedzieć, że może być inaczej :)

Ostatnie pytanie - no strzelałbym, że odpowiedź B (D-SUB), ale to trochę metodą eliminacji :) Bo na pewno nie jest to FireWire (bardziej kwadratowe i małe), HDMI (bardziej płaskie), USB (no to chyba tłumaczyć nie trzeba).

No generalnie wiedziałem, że to do karty grafiki, ale pewnie w pierwszym odruchu bym powiedział VGA a nie D-SUB :)
}
2010-06-23 10:51:15 = Wróżka z IRC
{
12:34:52 <+D0han> to nawet DVI-D nie jest jednak ;D
12:35:31 <+D0han> rogi zlacza sa zaokraglone odwrotnie
12:35:42 <+D0han> albo kreska jest nie po tej stronie co trzeba
12:35:58 <@komeniusz> Jakieś nowe porty wymyślają ;d
12:36:02 <+D0han> no
}
2010-06-23 10:52:41 = Dreadlish
{
Wygląda jak DVI i to jest DVI, ale ponoć wersja D, którą tu widać jest kompatybilna w 100% z HDMI, a więc odp nr. C.
}
2010-06-23 10:54:46 = Kuba
{
HDMI jest kompatybilne, ale musimy zastosować przejściówkę DVI-HDMI.
}
2010-06-23 10:56:18 = hxv
{
Znalazłem przed chwilą ten test i pytanie o port ma trochę inne odpowiedzi niż tutaj :> (D. DVI)
}
2010-06-23 11:01:03 = Kuba
{
A pytanie nr. 29 widzieliście? :)
http://dl.dropbox.com/u/1753596/zadanie.jpg
}
2010-06-23 11:03:42 = Gynvael Coldwind
{
@dr_bonzo
;DDD

@Mariusz Kędziora
No cóż, D-SUB to to nie jest oczywiście :)
Ale masz rację co do terminologii - też spotykałem się z "VGA" a nie "D-SUB" (tj. w końcu parę lat temu przy okazji zakupu monitora i karty graficznej się tego D-SUB nauczyłem ;>).

@Wróżka z IRC
@Dreadlish
@Kuba
W zasadzie wasze komentarze tworzą całość :)
Zgadzam się, że jeśli odpowiedzią miałoby być HDMI, to powinni pokazać HDMI, a nie coś co można przejściówką skonwertować na HDMI (w końcu to może też być USB w tym wypadku - http://sewelldirect.com/articles/USB-to-HDMI.aspx) :)))

@hxv
Słyszałem pogłoski o istnieniu wersji o której mówisz, natomiast z dwóch różnych źródeł otrzymałem test z powyższą wersją :)
Mam nadzieje, że jakąś erratę rozdawali na egzamie or sth :)))

@Kuba
Dobree :)))
Pascal++ ;)))
}
2010-06-23 11:11:48 = Mariusz Kędziora
{
No i wyszło moje zacofanie technologiczno-sprzętowe :D
}
2010-06-23 12:50:39 = lego
{
To jakieś radio z lat 70 ubiegłego wieku
Ten port nazywa się unitra :)
}
2010-06-23 12:55:30 = jerrythemouse
{
na szczęście jestem zwolniony z części pisemnej ;)
pytania podchwytliwe z przypadku ;p
}
2010-06-23 13:06:38 = Jurgi Filodendryta
{
Widziałem komplet zadań na egzamin na technika informatyka – kuzyn się uczył w studium. Z informatyką mam tyle wspólnego, że mam komputer. Nie miałbym problemu zdać. Prace dyplomowe na tym poziomie też widziałem, a w zasadzie to je pisałem. :) Szczerze mówiąc, dla ludzi, którzy nie potrafiliby poprawnie złącza ATA wsadzić.

A co do fragmentu kodu: wydaje mi się, że znalazłyby się jeszcze inne (może ciut niszowe) języki, w których by to było poprawne.
}
2010-06-23 14:39:28 = ˙
{
Najciekawszy w podanym fragmencie kodu (z zadania) jest mimo wszystko sposób formatowania...
}
2010-06-23 15:42:58 = Tomasz Kowalczyk
{
Dzięki za kolejny ciekawy post - informacja o dolarach w Javie i C/C++ była dla mnie nowością. ;]

Co do ostatniego pytania - wygląda jak DVI-D, ale faktycznie, spojrzałem na wyjście karty graficznej i są istotne różnice. ;]
}
2010-06-23 16:36:41 = Nacir
{
Jest to D-Sub, czy byscie chcieli czy nie. Dlaczego ? bo pewnie test pisal jakis Dinozaur ktory defakto uznal iz, jesli ksztalt obramowki metalowej jest w postaci D to taka odpowiedz tam umiescil (nie wiedzac o nowych standardach). Czyli wnioskujac bylby to D-Sub. Niestety, te typy wyszly ze standardu domyslnych portow po wyjsciu portu USB wraz z DVI :) gdzie DVI nie jest juz porownywany do typu portow D-Sub, tylko DVI (ze wzgledu na DVI-I (oba), DVI-D (digital) oraz DVI-A(analog)).

Jesli chce ktos poczytac, niech zajrzy na strone ICIA (www.infocomm.org).

Badz co badz :) HDMI to na pewno nie jest i na 100% kompatybilnosci to sie nie dam nabrac :) Gdyz, pokazcie mi HDMI do DVI i jeszcze Audio :D hmmmm nie widzialem jeszcze :) Musisz miec specjalne pudeleczko zeby to robic :) czyli kompatybilne w 100% nie jest.

@ Wrozka z IRC
Hmm, a mi sie wydaje ze D0han myslal o wtyczce :) a nie porcie mowiac tak :D

Takze wg mnie jedyna odpowiedz racjonalnie prawdopodobna to B :) D-Sub :)
}
2010-06-23 17:47:47 = Gynvael Coldwind
{
@Mariusz Kędziora
Z tego co widzę komentarz Nacira (na który odpowiem za parę linii) to może jeszcze się okazać, że to D-SUB ;DDD

@lego
;)))))

@jerrythemouse
:D

@Jurgi Filodendryta
:)
Co do języków niszowych - mi się mIRC script skojarzył jak zobaczyłem $, ale chyba reszta syntaxu by nie przeszła :)


Taaaaak ;) Formatowanie "ma własny styl" ;)

@Tomasz Kowalczyk
Szczerze, to ja też niedawno dopiero się o $ dowiedziałem. A o $ w Javie dzisiaj ;D

@Nacir
Niestety, nie mogę się z tobą zgodzić. Imo to, że obramowanie jest w kształcie litery D nie przesądza jeszcze o tym, że jest to D-SUB. Szczególnie, że D-SUB ma "trapezową" obudowę, a DVI wygląda mi bardziej na prostokąt z mocno "zaokrąglonymi" rogami od dołu hehe :)
Po za tym warto zobaczyć http://pinouts.ru/connector/ - jest tam wymieniona masa D-SUB'ów, ale nie ma wśród nich DVI, które są osobno.
Szczerze to trochę szukałem, ale nie znalazłem źródła które by zaliczało DVI do D-SUBów - czy możesz takie podać? ;)

}
2010-06-23 18:19:17 = Nacir
{
Gyn,
No wlasnie nie. Jak juz pisalem w mojej wczesniejszej wypowiedzi, musiales przyjac tok myslenia DINOZAURA (ktory wyszedl na niedoczytanego w obecnych standardach).

Nie znajdziesz DVI w D-Sub'ach. DVI to (sorki, nie znam polskiego odpowiednika) Proprietary Port, takze odchodzi on od normy i standardow D-Sub, oraz nie powinien byc zaliczany do niego.

Ale jako ze wraz z regulka odnosnie D-Sub(miniature) jest powiedziane iz kazdy port z metalowa obramowka w ksztalcie litery D nalezy do typu D-Sub (zaznaczam, ze to strasznie stara regulka :) ), nie powinnismy nawet uznac DVI do tego.

Dodam, ze HDMI, tez to nie moze byc :) HDMI to HDMI (High Definition Multimedia Interface), gdzie DVI (Digital Visual Interface). Porownujac te 3 wspomniane typy, zadna nie powinna sie nachodzic, gdyz to osobny typ portu, posiadajacy wlasne standardy i nie zostaly one (2 ostatnie wymienione typy) poddane publicznej modyfikacji jak to sie tyczy z D-Sub :)

DVI nalezy/kierowane do Digital Display Working Group
HDMI natomiast do SONY (z tego co mi wiadomo - nie jest ono ogolnie wlascicielem, ale zarzadza wszystkie ustawy dotyczace standardow).
D-Sub, multum firm, ktore tworzyly wlasne odmiany tj, DB-9 (RS-232), HD-15 (VGA - polaczenie oglnie znane przez ludzi w swiecie kompow monitor-GPU), DB-25 o ile mnie pamiec nie myli to ISDN, Cisco i inne ...

Wiec skoro to nie D-Sub, to moze mi ktos pokazac ze DVI nalezy do grupy HDMI :D ??
Bo USB lub Fire Wire to w zupelnosci nie jest :)
}
2010-06-23 18:40:13 = Gynvael Coldwind
{
@Nacir
OK, załapałem :)
Kurcze, masz może skana jakieś książki gdzie D-SUB jest tak opisany? Wezmę przejrzę potem półki, taki old-schoolowy smaczek byłby dobry :)))

No HDMI to to na pewno nie jest :)

A problem polega na tym, że nie ma w tym pytaniu dobrej odpowiedzi (that's the funny part). Jak pisał hxv, krążą po sieci też wersje z D. DVI, czyli poprawne :)

@Mariusz Kędziora
No i widzisz, wyszło na to, że kiedyś zupełnie prawidłowo byłoby to nazwać D-SUB :)

Anyway, cool że się czegoś nauczyłem nowego: faktycznie wygląda na to że "port VGA" jest jak najbardziej poprawne, bo "D-SUB" określa grupę/rodzaj portów. VGA konkretniej byłoby DE-9 (na starszych kartach, o ile ktoś jeszcze takie pamięta; ja pamiętam ;>) lub HD-15 (jak napisał Nacir), czyli High Density, bo zamiast 2ch rzędów pinów są 3 (gęściej) ;>
Yaay ;)
}
2010-06-23 18:52:30 = Nacir
{
Gyn, mowiac "tak opisany" tzn jak :)

Gyn, dodam ze i DVI byloby nie dokladna odpowiedzia :) Natoamiast DVI-D byloby dobra :)
DVI to rodzaj, tamto co pokazane to typ :) zreszta "who cares" :D

Pozdrawiam.
}
2010-06-23 20:40:20 = Kuba
{
Nacir:
"Badz co badz :) HDMI to na pewno nie jest i na 100% kompatybilnosci to sie nie dam nabrac :) Gdyz, pokazcie mi HDMI do DVI i jeszcze Audio :D hmmmm nie widzialem jeszcze :) Musisz miec specjalne pudeleczko zeby to robic :) czyli kompatybilne w 100% nie jest."

A to akurat nie prawda. DVI mimo, iż służy do przesyłania obrazu ma możliwość przesyłu dźwięku ("DVI-D - przesyła tylko dane cyfrowe; w najnowszych kartach graficznych jest w pełni kompatybilne z HDMI (przesyła również dane dźwiękowe)." - wiki)
W sumie DVI to takie HDMI z innym pinoutem + dodatkowymi pinami na sygnał analogowy.


DB-25 możemy znaleźć w komputerze jako port równoległy.
}
2010-06-23 22:19:30 = Mariusz Kędziora
{
Ale to teraz nie wiem czy się cieszyć czy smucić tym, że może jednak moja odpowiedź mogła być choć trochę prawidłowa...

Bo jeśli jest teoretycznie prawidłowa to o ile dobrze zrozumiałem to jestem... dinozaurem :D No faktycznie pamiętam Windows 3.1 i zaczynałem n lat temu od Basica z numerowanymi liniami na Commodore C64, ale chyba aż taki dinozaurowaty nie jestem :D
}
2010-06-23 23:04:09 = Gynvael Coldwind
{
@Nacir
Tya, masz rację z tym DVI-D ;)

@Kuba
:)

@Mariusz Kędziora
10 Nie no, na 8-bitowce nadal wychodzą nowe gry
20 więc chyba to nie są aż takie zamierzchłe czasy :)
30 :)

--
Z refererów:
http://czerwinski.info.pl/2010/06/ile-wynosi-100/ - filozoficzno ekonomiczny kod w javie - ile na prawdę jest warte 100 dolarów ? :DDDD

}
2010-06-24 08:08:44 = piatkosia
{
Co do egzaminu: była wersja X, Y, Z ... i one różniły się odpowiedziami, a czasami tylko ich kolejnością. To pewnie było powodem, że ktoś miał inne odp.
}
2010-06-25 14:08:36 = lzsk
{
http://www.atmarkit.co.jp/fsys/cableconnect/05disp_video/03dvi_d-box-l.jpg
sorry jak już wiadomo co to jest i link się powtarza .. ale nie mam czasu na przeczytanie tylu komentarzy .. :)
}
2010-06-26 13:52:11 = rousseau
{
Wróżka z IRC,
z jakiego kanału pochodzi ta rozmowa?
}
2010-06-26 14:13:04 = MDobak
{
Egzamin maturalny z informatyki w tym roku też był... hmm... ciekawy ;-).
}
2010-06-27 11:12:48 = szczypmen
{
http://pl.wikipedia.org/wiki/Digital_Visual_Interface

DVI-D tyle że odwrócony.
}
2010-06-27 22:29:14 = Dreadlish
{
@szczypmen
Walnęli po prostu gniazdo, a nie wtyczkę.

@pozatematem
Gynvael, planujesz jeszcze coś robić z reversecraftem? Bo tak troche patrzę, to projekt zaczyna zamierać.
}
2010-07-03 15:50:11 = Ursus
{
Ciekawostka (informacja poniekąd związana z newsem):

22 czerwca 2010 roku dyrektor Zespołu Szkół Elektroniczno-Telekomunikacyjnych w Lesznie przedwcześnie przeprowadził etap praktyczny egzaminu w zawodzie technik elektronik. Zgodnie z harmonogramem egzamin ten powinien być przeprowadzony 23 czerwca br. Dlatego też etap praktyczny tegorocznego egzaminu zawodowego na technika elektronika został unieważniony.

W niektórych zawodach timing naprawdę ma znaczenie :)
}
2010-07-04 09:07:13 = Sergi
{
Po prostu osoba przechylająca się za komputer zobaczyła port do góry nogami i ot, cała filozofia ;)
Można jeszcze pokazać kilka ciekawych pytań, które padły na teście, m.in. adresowanie sieci (gdzie dwie odpowiedzi były prawidłowe), oraz pytanie 40. z ipconfig, gdzie za prawidłowe można było uznać aż 3.
Pole do popisu dla odwołujących się jest całkiem spore :D
}
2010-07-04 12:14:53 = Ursus
{
Nie tylko z egzaminem na informatyka tak jest, na inne zawody jest podobnie, na szczescie zwykle z roku na rok jest lepiej.
}

Add a comment:

Nick:
URL (optional):
Math captcha: 8 ∗ 9 + 8 =