Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

gcc - jak być ostrzeżonym o braku deklaracji specjalizacji szablonu?

3 views
Skip to first unread message

Paweł Kierski

unread,
Dec 21, 2009, 7:59:06 AM12/21/09
to
Uwaga, dzieci! Poniższy kod jest ZŁY! Przekonałem się o tym
na własnej skórze i dlatego chciałbym być na przyszłość ostrzegany przez
kompilator.

W skrócie: w pliku nagłówkowym zabrakło deklaracji specjalizacji
szablonu. Kod wygląda tak:

::::::::::::::
templ.h
::::::::::::::
#ifndef TEMPL_H__
#define TEMPL_H__

#include <iostream>

template<typename T> void foo(const T& x) {
std::cout << "template<typename T> void foo(const T& x)\n";
}

// tu zabrakło:
// template<> void foo(const std::string& s);

#endif

::::::::::::::
templ.cc
::::::::::::::
#include "templ.h"

template<> void foo(const std::string& s) {
std::cout << "template<> void foo(const std::string& s)\n";
}

::::::::::::::
main.cc
::::::::::::::
#include "templ.h"

int main() {
foo(1);
foo(std::string("abc"));
}
::::::::::::::

VC przy linkowaniu daje błąd: "one or more multiply defined symbols
found".

g++ niestety zawiódł - kompilując z opcjami -pedantic -Wall wszystko
przeszło bez zająknięcia. Wynik:
---
template<typename T> void foo(const T& x)
template<> void foo(const std::string& s)
---
Po dodaniu opcji -O3 wynik się "nieco zmienił:
---
template<typename T> void foo(const T& x)
template<typename T> void foo(const T& x)
---

Pytanie - czy jakoś można zmusić g++, żeby reagował na takie
przypadki co najmniej ostrzeżeniem? Szukam właśnie po opcjach, ale na
razie nie mam pomysłu...

--
Paweł Kierski
ne...@pkierski.net

Paweł Kierski

unread,
Dec 21, 2009, 8:24:59 AM12/21/09
to
Paweł Kierski wrote:
[...]

> Pytanie - czy jakoś można zmusić g++, żeby reagował na takie
> przypadki co najmniej ostrzeżeniem? Szukam właśnie po opcjach, ale na
> razie nie mam pomysłu...

Pewnym sposobem jest po prostu unikanie specjalizacji szablonów na
rzecz przeciążania. Wtedy przynajmniej bez optymalizacji też "nie
działa", tzn. używa ogólnej wersji z szablonu, bo nie widzi deklaracji
przeciążonej funkcji. Ale to jednak półśrodek...

--
Paweł Kierski
ne...@pkierski.net

arturbac

unread,
Dec 21, 2009, 8:32:00 AM12/21/09
to
Cos w desen :
Użyc czesciowej specjalizacji i wprowdzic dodatkowy parametr wzorca U np
bool i wstawiac tam U=IS_POD_TYPE<T>
1) dla T,U w ogolnosci static assert
2) np dla T,IS_POD_TYPE<T> czesciowa specjalizacja T,true
3) dla wszystkich nie PODow specjalizacja pelna

Paweł Kierski

unread,
Dec 21, 2009, 8:36:24 AM12/21/09
to

To się akurat sprawdzi w moim przypadku - ogólna wersja służy do
dodawania zawartości binarnej do bufora. Czyli ogólna jest dla PODów,
a specjalizacje dla nie-PODów. Gorzej, jeśli ktoś będzie chciał mieć
specjalizację dla jakiegoś PODa - też się natnie.

--
Paweł Kierski
ne...@pkierski.net

Sebastian Nibisz

unread,
Dec 21, 2009, 1:15:05 PM12/21/09
to
Paweł Kierski wrote:
> Pytanie - czy jakoś można zmusić g++, żeby reagował na takie
> przypadki co najmniej ostrzeżeniem? Szukam właśnie po opcjach, ale na
> razie nie mam pomysłu...

Sprawdziłem i u mnie g++ w wersji 4.4.0, kończy kompilację błędem:
"multiple definition of `void foo<std::string>(std::string const&)'"

Pozdrawiam,
- Bastek -

Paweł Kierski

unread,
Dec 22, 2009, 4:13:44 AM12/22/09
to

U mnie 4.2.3 - nie dopisałem tej informacji.

--
Paweł Kierski
ne...@pkierski.net

Sebastian Nibisz

unread,
Dec 22, 2009, 4:22:12 AM12/22/09
to
Paweł Kierski wrote:
>> Sprawdziłem i u mnie g++ w wersji 4.4.0, kończy kompilację błędem:
>> "multiple definition of `void foo<std::string>(std::string const&)'"
>
> U mnie 4.2.3 - nie dopisałem tej informacji.

Ja też nie dopisałem a pewnie to ważne - kompilacja bez optymalizacji.

Pozdrawiam,
- Bastek -

0 new messages