public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/56760] New: namespaces, templates and forwarding declarations.
@ 2013-03-28  7:00 erik.thiele@thiele-hydraulik.de
  2013-03-28  7:01 ` [Bug c++/56760] " erik.thiele@thiele-hydraulik.de
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: erik.thiele@thiele-hydraulik.de @ 2013-03-28  7:00 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

             Bug #: 56760
           Summary: namespaces, templates and forwarding declarations.
    Classification: Unclassified
           Product: gcc
           Version: 4.7.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: erik.thiele@thiele-hydraulik.de


Created attachment 29739
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29739
v1 source code


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/56760] namespaces, templates and forwarding declarations.
  2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
@ 2013-03-28  7:01 ` erik.thiele@thiele-hydraulik.de
  2013-03-28  7:05 ` erik.thiele@thiele-hydraulik.de
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: erik.thiele@thiele-hydraulik.de @ 2013-03-28  7:01 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

--- Comment #1 from erik.thiele@thiele-hydraulik.de 2013-03-28 07:01:12 UTC ---
Created attachment 29740
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29740
v2 source code


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/56760] namespaces, templates and forwarding declarations.
  2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
  2013-03-28  7:01 ` [Bug c++/56760] " erik.thiele@thiele-hydraulik.de
@ 2013-03-28  7:05 ` erik.thiele@thiele-hydraulik.de
  2013-03-28  7:14 ` pinskia at gcc dot gnu.org
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: erik.thiele@thiele-hydraulik.de @ 2013-03-28  7:05 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

--- Comment #2 from erik.thiele@thiele-hydraulik.de 2013-03-28 07:05:22 UTC ---
You see attached two files. v1.cpp and v2.cpp

g++ --version
g++ (Debian 4.7.2-5) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

g++ -Wall v1.cpp
/tmp/ccZAyNEb.o: In function `void func<seco::holder<int>
>(seco::contain<seco::holder<int> > const&, nam::binbuffer&)':
v1.cpp:(.text._Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE[_Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE]+0x16):
undefined reference to `void func<seco::holder<int> >(seco::holder<int> const&,
nam::binbuffer&)'
collect2: error: ld returned 1 exit status

g++ -Wall v2.cpp
--> no errors

in v1.cpp you see a commented out line with a template forward declaration. if
you comment that in:

g++ -Wall v1.cpp
--> no errors

The only difference between v1 and v2 is that in v2 you do not have the "nam"
namespace.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/56760] namespaces, templates and forwarding declarations.
  2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
  2013-03-28  7:01 ` [Bug c++/56760] " erik.thiele@thiele-hydraulik.de
  2013-03-28  7:05 ` erik.thiele@thiele-hydraulik.de
@ 2013-03-28  7:14 ` pinskia at gcc dot gnu.org
  2013-03-28  7:58 ` erik.thiele@thiele-hydraulik.de
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: pinskia at gcc dot gnu.org @ 2013-03-28  7:14 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> 2013-03-28 07:14:14 UTC ---
Note I think this undefined code at compile time due to specializations happen
after their use though the reason why it fails are a different reason.

This is expected behavior for the following reason:
In the second case, we have an argument dependent lookup that happens in the
global namespace so the overloaded set includes all of them at instantiation
time too.  So it picks the one which is specialized for seco::holder<T>.

But in the first case the overload set only includes the first two and does not
know about one for seco::holder<T> and never looks for it as argument depend
lookup only happens in seco and nam as the two argument types are located in
those namespaces.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/56760] namespaces, templates and forwarding declarations.
  2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
                   ` (2 preceding siblings ...)
  2013-03-28  7:14 ` pinskia at gcc dot gnu.org
@ 2013-03-28  7:58 ` erik.thiele@thiele-hydraulik.de
  2013-03-28  8:22 ` erik.thiele@thiele-hydraulik.de
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: erik.thiele@thiele-hydraulik.de @ 2013-03-28  7:58 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

--- Comment #4 from erik.thiele@thiele-hydraulik.de 2013-03-28 07:58:00 UTC ---
The example is reduced very much. Actually I have a module for "holder" and one
for "contain" (separate compilation units). They do not know about each other.
I have this global mechanism called "func" which everybody can make
specializations for to enable his class to take part in this "func" stuff. What
func does is serialize a class into the "binbuffer" binary buffer. If you
create a custom class, you can let it take part in the "func" system and thus
make it serializable.

Everything works fine until I have a holder<contain<foo> > or a
contain<holder<foo> >. The problem is that I cannot have a forward declaration
because "contain" and "holder" don't know each other. This is like adding
forward declarations in system libraries like "vector<>" for user classes which
the STL developers of course cannot know.

v2.cpp does not have the "nam" namespace that "v1.cpp" has. But the "nam"
namespace is only for the "binbuffer" class. See that it has nothing to do with
the "seco" namespace or the global namespace that "func" is inside. For that
reason I do not understand why leaving out the "nam" namespace fixes the
problem.

I cannot find a workaround. The problem is that template implementations are
inside headers. So either "holder" or "contain" is defined and implemented
first. I cannot define "holder" and "contain" and then afterwards implement
"holder" and "contain". This would fix my problem but then the template
implementation cannot be inside the header anymore, at least I do not know how.
I would need a precompiler that splits header interfaces from header
implementations and first puts all interfaces and then all implementations.

Is there another workaround?

Sorry I do not understand your comment. Probably I miss some important point
somehow. Anyway I do not find a solution...


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/56760] namespaces, templates and forwarding declarations.
  2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
                   ` (3 preceding siblings ...)
  2013-03-28  7:58 ` erik.thiele@thiele-hydraulik.de
@ 2013-03-28  8:22 ` erik.thiele@thiele-hydraulik.de
  2013-03-28  8:27 ` erik.thiele@thiele-hydraulik.de
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: erik.thiele@thiele-hydraulik.de @ 2013-03-28  8:22 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

--- Comment #5 from erik.thiele@thiele-hydraulik.de 2013-03-28 08:22:19 UTC ---
Created attachment 29741
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29741
v3 source code


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/56760] namespaces, templates and forwarding declarations.
  2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
                   ` (4 preceding siblings ...)
  2013-03-28  8:22 ` erik.thiele@thiele-hydraulik.de
@ 2013-03-28  8:27 ` erik.thiele@thiele-hydraulik.de
  2013-03-28  9:16 ` redi at gcc dot gnu.org
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: erik.thiele@thiele-hydraulik.de @ 2013-03-28  8:27 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

--- Comment #6 from erik.thiele@thiele-hydraulik.de 2013-03-28 08:27:34 UTC ---
let me paste "v3 source code" that is also added as attachment:


namespace nam { class binbuffer {}; }

template<class T> void func (const T &a, nam::binbuffer &b);

namespace seco {
  template<class X> struct holder { X *fun; };
  template<class T> struct contain { T *wombat; };
}

template<class T> void func(const seco::contain<T> &a, nam::binbuffer &b)
{ func(*a.wombat, b); }

template<class T> void func(const seco::holder<T> &a, nam::binbuffer &b)
{ func(*a.fun, b); }

template<> void func(const int &a, nam::binbuffer &b) {}

int main()
{
  nam::binbuffer b;
  seco::holder<int> foo;
  func(foo, b);
  seco::contain<seco::holder<int> > containHolder;
  func(containHolder, b); // COMMENT THIS OUT AND IT WORKS
  return 0;
}


END OF CODE


when you compile this, it sais

g++ -Wall v3.cpp
/tmp/ccDElJvq.o: In function `void func<seco::holder<int>
>(seco::contain<seco::holder<int> > const&, nam::binbuffer&)':
v3.cpp:(.text._Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE[_Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE]+0x16):
undefined reference to `void func<seco::holder<int> >(seco::holder<int> const&,
nam::binbuffer&)'
collect2: error: ld returned 1 exit status


but when you comment out the line "COMMENT THIS OUT AND IT WORKS" then it
compiles.

now consider the line "func(foo, b)". here exactly the function gets called
that the linker sais is not defined. How can the linker say the function is not
defined, even though it obviously is defined?

you can make it even more clear: comment out this:

//template<class T> void func(const seco::holder<T> &a, nam::binbuffer &b)
//{ func(*a.fun, b); }

but reenable the line "COMMENT THIS OUT AND IT WORKS"

then you get this output:

g++ -Wall v3.cpp
/tmp/cc3keqh3.o: In function `main':
v3.cpp:(.text+0x1e): undefined reference to `void func<seco::holder<int>
>(seco::holder<int> const&, nam::binbuffer&)'
/tmp/cc3keqh3.o: In function `void func<seco::holder<int>
>(seco::contain<seco::holder<int> > const&, nam::binbuffer&)':
v3.cpp:(.text._Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE[_Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE]+0x16):
undefined reference to `void func<seco::holder<int> >(seco::holder<int> const&,
nam::binbuffer&)'
collect2: error: ld returned 1 exit status

you see, it sais two times that the function is not defined. that's OK! now if
you reenable:

template<class T> void func(const seco::holder<T> &a, nam::binbuffer &b)
{ func(*a.fun, b); }

then only the second error message keeps being there. but it misses exactly the
same function!

what's going on here? the function is there and it gets called once. why cannot
it get called twice???


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/56760] namespaces, templates and forwarding declarations.
  2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
                   ` (5 preceding siblings ...)
  2013-03-28  8:27 ` erik.thiele@thiele-hydraulik.de
@ 2013-03-28  9:16 ` redi at gcc dot gnu.org
  2013-03-28  9:55 ` erik.thiele@thiele-hydraulik.de
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2013-03-28  9:16 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> 2013-03-28 09:16:52 UTC ---
Read the section on name lookup changes at
http://gcc.gnu.org/gcc-4.7/porting_to.html


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/56760] namespaces, templates and forwarding declarations.
  2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
                   ` (6 preceding siblings ...)
  2013-03-28  9:16 ` redi at gcc dot gnu.org
@ 2013-03-28  9:55 ` erik.thiele@thiele-hydraulik.de
  2013-03-28 11:05 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: erik.thiele@thiele-hydraulik.de @ 2013-03-28  9:55 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

--- Comment #8 from erik.thiele@thiele-hydraulik.de 2013-03-28 09:55:49 UTC ---
I read the section on name lookup changes at
http://gcc.gnu.org/gcc-4.7/porting_to.html

but it talks about a different kind of problem. Consider that there the
compiler does error messages. But here at our problem the linker (!) does the
error.

also the mentioned -fpermissive flag does not change the situation.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/56760] namespaces, templates and forwarding declarations.
  2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
                   ` (7 preceding siblings ...)
  2013-03-28  9:55 ` erik.thiele@thiele-hydraulik.de
@ 2013-03-28 11:05 ` redi at gcc dot gnu.org
  2013-03-28 16:50 ` erik.thiele@thiele-hydraulik.de
  2013-03-28 17:19 ` redi at gcc dot gnu.org
  10 siblings, 0 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2013-03-28 11:05 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> 2013-03-28 11:05:26 UTC ---
(In reply to comment #8)
> I read the section on name lookup changes at
> http://gcc.gnu.org/gcc-4.7/porting_to.html
> 
> but it talks about a different kind of problem. Consider that there the
> compiler does error messages. But here at our problem the linker (!) does the
> error.

It's the same problem.  You get a linker error because this line:

  func(containHolder, b); // COMMENT THIS OUT AND IT WORKS

calls this function:

  template<class T> void func(const seco::contain<T> &a, nam::binbuffer &b)
  { func(*a.wombat, b); }

which then calls this function:

  template<class T> void func (const T &a, nam::binbuffer &b);

which is not defined. So you get a linker error.

You are expecting it to call this function:

  template<class T> void func(const seco::holder<T> &a, nam::binbuffer &b)
  { func(*a.fun, b); }

but it cannot, because that is not declared before it is used. This is the
situation described in the name lookup changes.

Your code is not valid C++, the compiler is correct.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/56760] namespaces, templates and forwarding declarations.
  2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
                   ` (8 preceding siblings ...)
  2013-03-28 11:05 ` redi at gcc dot gnu.org
@ 2013-03-28 16:50 ` erik.thiele@thiele-hydraulik.de
  2013-03-28 17:19 ` redi at gcc dot gnu.org
  10 siblings, 0 replies; 12+ messages in thread
From: erik.thiele@thiele-hydraulik.de @ 2013-03-28 16:50 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

--- Comment #10 from erik.thiele@thiele-hydraulik.de 2013-03-28 16:50:06 UTC ---
But the function actually IS defined, because the call func(foo,b) works. Yes
it is not defined early enough maybe. But the linker is run after the compiler.
How can the linker differentiate about when something is implemented? doesn't
it just look for the symbol and if it is there, then it is there?

as mentioned in my post 2013-03-28 08:27:34 UTC the signature of the missing
implementation is exactly the same in the error message if you leave out the
template definition than if you do the line that you call invalid C++.

So maybe the linker output should show more detail. The linker sais that an
implementation is missing, which is NOT missing. so maybe there is some
additional clue that the linker could display here? is there some hidden
additional information in the function signature somehow?


the section about name lookup changes talks about the -fpermissive option which
should reactivate the old behaviour. but that does not work.


anyway... what could be a workaround? as mentioned earlier I cannot do a
forward declaration.

This really puzzles me...


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Bug c++/56760] namespaces, templates and forwarding declarations.
  2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
                   ` (9 preceding siblings ...)
  2013-03-28 16:50 ` erik.thiele@thiele-hydraulik.de
@ 2013-03-28 17:19 ` redi at gcc dot gnu.org
  10 siblings, 0 replies; 12+ messages in thread
From: redi at gcc dot gnu.org @ 2013-03-28 17:19 UTC (permalink / raw)
  To: gcc-bugs


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56760

--- Comment #11 from Jonathan Wakely <redi at gcc dot gnu.org> 2013-03-28 17:19:06 UTC ---
(In reply to comment #10)
> But the function actually IS defined,

No it isn't! Please read my answer again carefully.

The function that gets called is 

template<class T> void func (const T &a, nam::binbuffer &b);

and NOT

template<class T> void func(const seco::holder<T> &a, nam::binbuffer &b)
{ func(*a.fun, b); }

These are not the same function, and the first one is NOT defined.


> because the call func(foo,b) works.

That comes *after* the relevant function is defined, so name lookup finds it.

> Yes
> it is not defined early enough maybe. But the linker is run after the compiler.

Irrelevant. The call to func(*a.wombat, b) finds a function template that is
not defined. The compiler generates a reference to a particular function, the
linker can't decide to link it to a different function just because you think
they're similar.


> How can the linker differentiate about when something is implemented? doesn't
> it just look for the symbol and if it is there, then it is there?

Because the call doesn't use the function you think it does!


> as mentioned in my post 2013-03-28 08:27:34 UTC the signature of the missing
> implementation is exactly the same in the error message if you leave out the
> template definition than if you do the line that you call invalid C++.

No, they are *not* the same, try using 'nm' to see they are different symbols:

                 U _Unwind_Resume
0000000000000000 W
_Z4funcIN4seco6holderIiEEEvRKNS0_7containIT_EERN3nam9binbufferE
                 U _Z4funcIN4seco6holderIiEEEvRKT_RN3nam9binbufferE
0000000000000000 W _Z4funcIiEvRKN4seco6holderIT_EERN3nam9binbufferE
0000000000000000 T _Z4funcIiEvRKT_RN3nam9binbufferE
                 U __gxx_personality_v0
000000000000000e T main

The missing definition is

                 U _Z4funcIN4seco6holderIiEEEvRKT_RN3nam9binbufferE

and the defined one is:

0000000000000000 W _Z4funcIiEvRKN4seco6holderIT_EERN3nam9binbufferE

THESE ARE NOT THE SAME SYMBOL!

Demangled, the names are:

                 U void func<seco::holder<int> >(seco::holder<int> const&,
nam::binbuffer&)
0000000000000000 W void func<int>(seco::holder<int> const&, nam::binbuffer&)

THESE ARE NOT THE SAME SYMBOL!


> So maybe the linker output should show more detail. The linker sais that an
> implementation is missing, which is NOT missing.

You're wrong. Look at the symbols.


> so maybe there is some
> additional clue that the linker could display here? is there some hidden
> additional information in the function signature somehow?

It's not hidden, it's right there in the signature but you're refusing to read
it:

x.C:11: undefined reference to
 `void func<seco::holder<int> >(seco::holder<int> const&, nam::binbuffer&)'
            ^^^^^^^^^^^^^^^^^
Look at the template argument list. Are you sure you defined it?
Look at the symbols again, with whitespace added to help:

U void func<seco::holder<int> >(seco::holder<int> const&, nam::binbuffer&)
W void func<int>               (seco::holder<int> const&, nam::binbuffer&)

Can you see what's different yet?

> the section about name lookup changes talks about the -fpermissive option which
> should reactivate the old behaviour. but that does not work.

I didn't say -fpermissive would work, but the text describes how name lookup
only finds names that are visible at the point of definition, or can be found
by ADL at the point of instantiation.

> anyway... what could be a workaround? as mentioned earlier I cannot do a
> forward declaration.

It's not GCC's job or my job to fix your code, please try somewhere more
suitable like stackoverflow.com


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2013-03-28 17:19 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-28  7:00 [Bug c++/56760] New: namespaces, templates and forwarding declarations erik.thiele@thiele-hydraulik.de
2013-03-28  7:01 ` [Bug c++/56760] " erik.thiele@thiele-hydraulik.de
2013-03-28  7:05 ` erik.thiele@thiele-hydraulik.de
2013-03-28  7:14 ` pinskia at gcc dot gnu.org
2013-03-28  7:58 ` erik.thiele@thiele-hydraulik.de
2013-03-28  8:22 ` erik.thiele@thiele-hydraulik.de
2013-03-28  8:27 ` erik.thiele@thiele-hydraulik.de
2013-03-28  9:16 ` redi at gcc dot gnu.org
2013-03-28  9:55 ` erik.thiele@thiele-hydraulik.de
2013-03-28 11:05 ` redi at gcc dot gnu.org
2013-03-28 16:50 ` erik.thiele@thiele-hydraulik.de
2013-03-28 17:19 ` redi at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).