Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Template instantiation context

Reply
Thread Tools

Template instantiation context

 
 
Juha Nieminen
Guest
Posts: n/a
 
      07-18-2009
Assume we have these three files:

//--------------------------------------------------------------
// foo.hh
#include <iostream>

template<typename T>
void foo(T value)
{
static int s = 0;
++s;
std::cout << "value:" << value << ", s:" << s
<< ", externalVar:" << externalVar << std::endl;
}
//--------------------------------------------------------------

//--------------------------------------------------------------
// bar.cc
namespace { const int externalVar = 456; }
#include "foo.hh"

void bar()
{
std::cout << "In bar(): ";
foo(200);
}
//--------------------------------------------------------------

//--------------------------------------------------------------
// test.cc
namespace { const int externalVar = 123; }
#include "foo.hh"

void bar();

int main()
{
std::cout << "In main(): ";
foo(100);
bar();
}
//--------------------------------------------------------------

Now we compile test.cc and bar.cc into an executable program. What
should be the output of this program?
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      07-18-2009
* Juha Nieminen:
> Assume we have these three files:
>
> //--------------------------------------------------------------
> // foo.hh
> #include <iostream>
>
> template<typename T>
> void foo(T value)
> {
> static int s = 0;
> ++s;
> std::cout << "value:" << value << ", s:" << s
> << ", externalVar:" << externalVar << std::endl;
> }
> //--------------------------------------------------------------
>
> //--------------------------------------------------------------
> // bar.cc
> namespace { const int externalVar = 456; }
> #include "foo.hh"
>
> void bar()
> {
> std::cout << "In bar(): ";
> foo(200);
> }
> //--------------------------------------------------------------
>
> //--------------------------------------------------------------
> // test.cc
> namespace { const int externalVar = 123; }
> #include "foo.hh"
>
> void bar();
>
> int main()
> {
> std::cout << "In main(): ";
> foo(100);
> bar();
> }
> //--------------------------------------------------------------
>
> Now we compile test.cc and bar.cc into an executable program. What
> should be the output of this program?


It's UB.

Btw., please don't formulate real questions so that they sound like homework.

If this question had any other answer than UB I would have believed it to be
homework.


Cheers & hth.,


- Alf
 
Reply With Quote
 
 
 
 
Juha Nieminen
Guest
Posts: n/a
 
      07-18-2009
Alf P. Steinbach wrote:
> Btw., please don't formulate real questions so that they sound like
> homework.


I don't know if you have seen me posting in this group before, but if
you have, you'd probably know that I have been in the business for long
enough that doing homework is way in the past for me by now...

This was a genuine question because I'm not completely sure how
template functions should work with respect to:

a) local static variables
b) variables in the outer scope

My best guess is that one type generates one single function (which,
if duplicated in more than one object file, gets merged by the linker),
in which case the static variable should be unique even when the
function is instantiated in more than one compilation unit. But that
raises the question what happens when the context is different (in this
case, when the variable name in the outer scope refers to different
variables in the two compilation units).

Rather than writing an essay as my question, I kept the post short and
simple.
 
Reply With Quote
 
Pavel
Guest
Posts: n/a
 
      07-18-2009
Alf P. Steinbach wrote:
> * Juha Nieminen:
>> Assume we have these three files:
>>
>> //--------------------------------------------------------------
>> // foo.hh
>> #include <iostream>
>>
>> template<typename T>
>> void foo(T value)
>> {
>> static int s = 0;
>> ++s;
>> std::cout << "value:" << value << ", s:" << s
>> << ", externalVar:" << externalVar << std::endl;
>> }
>> //--------------------------------------------------------------
>>
>> //--------------------------------------------------------------
>> // bar.cc
>> namespace { const int externalVar = 456; }
>> #include "foo.hh"
>>
>> void bar()
>> {
>> std::cout << "In bar(): ";
>> foo(200);
>> }
>> //--------------------------------------------------------------
>>
>> //--------------------------------------------------------------
>> // test.cc
>> namespace { const int externalVar = 123; }
>> #include "foo.hh"
>>
>> void bar();
>>
>> int main()
>> {
>> std::cout << "In main(): ";
>> foo(100);
>> bar();
>> }
>> //--------------------------------------------------------------
>>
>> Now we compile test.cc and bar.cc into an executable program. What
>> should be the output of this program?

>
> It's UB.
>
> Btw., please don't formulate real questions so that they sound like
> homework.
>
> If this question had any other answer than UB I would have believed it
> to be homework.

Why? It could be an interview questions but then OP would not be able to
use Internet. I can't see how it could be HW. It looks like a fully
compliant question to me.

-Pavel
 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      07-18-2009
Juha Nieminen wrote:
> Alf P. Steinbach wrote:
>> Btw., please don't formulate real questions so that they sound like
>> homework.

>
> I don't know if you have seen me posting in this group before, but
> if you have, you'd probably know that I have been in the business
> for long enough that doing homework is way in the past for me by
> now...
>
> This was a genuine question because I'm not completely sure how
> template functions should work with respect to:
>
> a) local static variables
> b) variables in the outer scope
>
> My best guess is that one type generates one single function
> (which, if duplicated in more than one object file, gets merged by
> the linker), in which case the static variable should be unique
> even when the function is instantiated in more than one compilation
> unit. But that raises the question what happens when the context is
> different (in this case, when the variable name in the outer scope
> refers to different variables in the two compilation units).
>
> Rather than writing an essay as my question, I kept the post short
> and simple.


By having different meanings for the for the name in the outer scope,
you have violated the One Definition Rule.

A template can be defined in several translation units, but the
meaning must be the same. Here it is not.


Bo Persson


 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      07-18-2009
* Pavel:
> Alf P. Steinbach wrote:
>> * Juha Nieminen:
>>> Assume we have these three files:
>>>
>>> //--------------------------------------------------------------
>>> // foo.hh
>>> #include <iostream>
>>>
>>> template<typename T>
>>> void foo(T value)
>>> {
>>> static int s = 0;
>>> ++s;
>>> std::cout << "value:" << value << ", s:" << s
>>> << ", externalVar:" << externalVar << std::endl;
>>> }
>>> //--------------------------------------------------------------
>>>
>>> //--------------------------------------------------------------
>>> // bar.cc
>>> namespace { const int externalVar = 456; }
>>> #include "foo.hh"
>>>
>>> void bar()
>>> {
>>> std::cout << "In bar(): ";
>>> foo(200);
>>> }
>>> //--------------------------------------------------------------
>>>
>>> //--------------------------------------------------------------
>>> // test.cc
>>> namespace { const int externalVar = 123; }
>>> #include "foo.hh"
>>>
>>> void bar();
>>>
>>> int main()
>>> {
>>> std::cout << "In main(): ";
>>> foo(100);
>>> bar();
>>> }
>>> //--------------------------------------------------------------
>>>
>>> Now we compile test.cc and bar.cc into an executable program. What
>>> should be the output of this program?

>>
>> It's UB.
>>
>> Btw., please don't formulate real questions so that they sound like
>> homework.
>>
>> If this question had any other answer than UB I would have believed it
>> to be homework.

> Why? It could be an interview questions but then OP would not be able to
> use Internet. I can't see how it could be HW. It looks like a fully
> compliant question to me.


The "What should be the output of this program?" triggered my HW recognition
meter. It is the form of the question, a code example followed by "what does
this do?", which is characteristic of homework and almost never what the author
of the code in question would ask. I ignored the HW meter needle's movement
because if it was homework then there would be a definite answer, not UB.


Cheers & hth.,

- Alf
 
Reply With Quote
 
Classic Wrinwright
Guest
Posts: n/a
 
      07-19-2009
g++ -Wall -g bar.cc test.cc produces:
In main(): value:100, s:1, externalVar:456
In bar(): value:200, s:2, externalVar:456

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      07-19-2009
On Jul 18, 7:43 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> * Juha Nieminen:


[...]
> > Now we compile test.cc and bar.cc into an executable
> > program. What should be the output of this program?


> It's UB.


> Btw., please don't formulate real questions so that they sound
> like homework.


> If this question had any other answer than UB I would have
> believed it to be homework.


I'd say that the author would have been enough; Juha's not
exactly new to this group. And I've not seen much homework
which involves separate compilation (or other things essential
when writing real code).

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      07-19-2009
Classic Wrinwright wrote:
> g++ -Wall -g bar.cc test.cc produces:
> In main(): value:100, s:1, externalVar:456
> In bar(): value:200, s:2, externalVar:456


Well, I didn't ask what gcc will print (because I can test that
myself). I asked what *should* be printed.

(OTOH, if the value printed for externalVar is indeed UB, then any
value would be as valid as anything else, I suppose.)
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      07-20-2009
On Jul 19, 2:00 pm, Juha Nieminen <(E-Mail Removed)> wrote:
> Classic Wrinwright wrote:
> > g++ -Wall -g bar.cc test.cc produces:
> > In main(): value:100, s:1, externalVar:456
> > In bar(): value:200, s:2, externalVar:456


> Well, I didn't ask what gcc will print (because I can test
> that myself).


Actually, you can't very well, since g++ doesn't define it any
more than the standard does. Thus (on my Linux box):

$ g++ -std=c++98 -pedantic bar.cc test.cc
$ a.out
In main(): value:100, s:1, externalVar:456
In bar(): value:200, s:2, externalVar:456
$ g++ -std=c++98 test.cc bar.cc
$ a.out
In main(): value:100, s:1, externalVar:123
In bar(): value:200, s:2, externalVar:123
$ g++ -std=c++98 -pedantic -O bar.cc test.cc
$ a.out
In main(): value:100, s:1, externalVar:123
In bar(): value:200, s:2, externalVar:456

So there is no correct answer to what g++ will print. (Which is
what undefined behavior is all about.)

> I asked what *should* be printed.


> (OTOH, if the value printed for externalVar is indeed UB, then
> any value would be as valid as anything else, I suppose.)


Anything the compiler does is valid. Including refusing to
compile the code. (IMHO, it wouldn't be that difficult to
detect the problem at link time, and generate an error message
then.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Instantiation of template method in template class Ed C++ 1 08-27-2008 06:41 AM
context in template point of instantiation (g++) carlos.urena.almagro@gmail.com C++ 4 01-16-2007 04:49 PM
Explicit instantiation of STL vector demands explicit instantiation of all the templates it using internally. krunalbauskar@gmail.com C++ 1 12-25-2006 03:51 PM
explicit instantiation of template methods of template classes Thomas Maier-Komor C++ 6 05-19-2005 08:00 AM
Explicit template instantiation from template function doesn't compile? Fernando Cuenca C++ 4 09-06-2004 04:06 PM



Advertisments