]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/doc/gcc/known-causes-of-trouble-with-gcc/common-misunderstandings-with-gnu-c.rst
sphinx: add missing trailing newline
[thirdparty/gcc.git] / gcc / doc / gcc / known-causes-of-trouble-with-gcc / common-misunderstandings-with-gnu-c.rst
1 ..
2 Copyright 1988-2022 Free Software Foundation, Inc.
3 This is part of the GCC manual.
4 For copying conditions, see the copyright.rst file.
5
6 .. index:: misunderstandings in C++, surprises in C++, C++ misunderstandings
7
8 .. _c++-misunderstandings:
9
10 Common Misunderstandings with GNU C++
11 *************************************
12
13 C++ is a complex language and an evolving one, and its standard
14 definition (the ISO C++ standard) was only recently completed. As a
15 result, your C++ compiler may occasionally surprise you, even when its
16 behavior is correct. This section discusses some areas that frequently
17 give rise to questions of this sort.
18
19 .. toctree::
20 :maxdepth: 2
21
22
23 .. index:: C++ static data, declaring and defining, static data in C++, declaring and defining, declaring static data in C++, defining static data in C++
24
25 .. _static-definitions:
26
27 Declare and Define Static Members
28 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
29
30 When a class has static data members, it is not enough to *declare*
31 the static member; you must also *define* it. For example:
32
33 .. code-block:: c++
34
35 class Foo
36 {
37 ...
38 void method();
39 static int bar;
40 };
41
42 This declaration only establishes that the class ``Foo`` has an
43 ``int`` named ``Foo::bar``, and a member function named
44 ``Foo::method``. But you still need to define *both*
45 ``method`` and ``bar`` elsewhere. According to the ISO
46 standard, you must supply an initializer in one (and only one) source
47 file, such as:
48
49 .. code-block:: c++
50
51 int Foo::bar = 0;
52
53 Other C++ compilers may not correctly implement the standard behavior.
54 As a result, when you switch to :command:`g++` from one of these compilers,
55 you may discover that a program that appeared to work correctly in fact
56 does not conform to the standard: :command:`g++` reports as undefined
57 symbols any static data members that lack definitions.
58
59 .. index:: base class members, two-stage name lookup, dependent name lookup
60
61 .. _name-lookup:
62
63 Name Lookup, Templates, and Accessing Members of Base Classes
64 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
65
66 The C++ standard prescribes that all names that are not dependent on
67 template parameters are bound to their present definitions when parsing
68 a template function or class.The C++ standard just uses the
69 term 'dependent' for names that depend on the type or value of
70 template parameters. This shorter term will also be used in the rest of
71 this section.
72
73 Only names that are dependent are looked up at the point
74 of instantiation. For example, consider
75
76 .. code-block:: c++
77
78 void foo(double);
79
80 struct A {
81 template <typename T>
82 void f () {
83 foo (1); // 1
84 int i = N; // 2
85 T t;
86 t.bar(); // 3
87 foo (t); // 4
88 }
89
90 static const int N;
91 };
92
93 Here, the names ``foo`` and ``N`` appear in a context that does
94 not depend on the type of ``T``. The compiler will thus require that
95 they are defined in the context of use in the template, not only before
96 the point of instantiation, and will here use ``::foo(double)`` and
97 ``A::N``, respectively. In particular, it will convert the integer
98 value to a ``double`` when passing it to ``::foo(double)``.
99
100 Conversely, ``bar`` and the call to ``foo`` in the fourth marked
101 line are used in contexts that do depend on the type of ``T``, so
102 they are only looked up at the point of instantiation, and you can
103 provide declarations for them after declaring the template, but before
104 instantiating it. In particular, if you instantiate ``A::f<int>``,
105 the last line will call an overloaded ``::foo(int)`` if one was
106 provided, even if after the declaration of ``struct A``.
107
108 This distinction between lookup of dependent and non-dependent names is
109 called two-stage (or dependent) name lookup. G++ implements it
110 since version 3.4.
111
112 Two-stage name lookup sometimes leads to situations with behavior
113 different from non-template codes. The most common is probably this:
114
115 .. code-block:: c++
116
117 template <typename T> struct Base {
118 int i;
119 };
120
121 template <typename T> struct Derived : public Base<T> {
122 int get_i() { return i; }
123 };
124
125 In ``get_i()``, ``i`` is not used in a dependent context, so the
126 compiler will look for a name declared at the enclosing namespace scope
127 (which is the global scope here). It will not look into the base class,
128 since that is dependent and you may declare specializations of
129 ``Base`` even after declaring ``Derived``, so the compiler cannot
130 really know what ``i`` would refer to. If there is no global
131 variable ``i``, then you will get an error message.
132
133 In order to make it clear that you want the member of the base class,
134 you need to defer lookup until instantiation time, at which the base
135 class is known. For this, you need to access ``i`` in a dependent
136 context, by either using ``this->i`` (remember that ``this`` is of
137 type ``Derived<T>*``, so is obviously dependent), or using
138 ``Base<T>::i``. Alternatively, ``Base<T>::i`` might be brought
139 into scope by a ``using`` -declaration.
140
141 Another, similar example involves calling member functions of a base
142 class:
143
144 .. code-block:: c++
145
146 template <typename T> struct Base {
147 int f();
148 };
149
150 template <typename T> struct Derived : Base<T> {
151 int g() { return f(); };
152 };
153
154 Again, the call to ``f()`` is not dependent on template arguments
155 (there are no arguments that depend on the type ``T``, and it is also
156 not otherwise specified that the call should be in a dependent context).
157 Thus a global declaration of such a function must be available, since
158 the one in the base class is not visible until instantiation time. The
159 compiler will consequently produce the following error message:
160
161 .. code-block::
162
163 x.cc: In member function `int Derived<T>::g()':
164 x.cc:6: error: there are no arguments to `f' that depend on a template
165 parameter, so a declaration of `f' must be available
166 x.cc:6: error: (if you use `-fpermissive', G++ will accept your code, but
167 allowing the use of an undeclared name is deprecated)
168
169 To make the code valid either use ``this->f()``, or
170 ``Base<T>::f()``. Using the :option:`-fpermissive` flag will also let
171 the compiler accept the code, by marking all function calls for which no
172 declaration is visible at the time of definition of the template for
173 later lookup at instantiation time, as if it were a dependent call.
174 We do not recommend using :option:`-fpermissive` to work around invalid
175 code, and it will also only catch cases where functions in base classes
176 are called, not where variables in base classes are used (as in the
177 example above).
178
179 Note that some compilers (including G++ versions prior to 3.4) get these
180 examples wrong and accept above code without an error. Those compilers
181 do not implement two-stage name lookup correctly.
182
183 .. index:: temporaries, lifetime of, portions of temporary objects, pointers to
184
185 .. _temporaries:
186
187 Temporaries May Vanish Before You Expect
188 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
189
190 It is dangerous to use pointers or references to *portions* of a
191 temporary object. The compiler may very well delete the object before
192 you expect it to, leaving a pointer to garbage. The most common place
193 where this problem crops up is in classes like string classes,
194 especially ones that define a conversion function to type ``char *``
195 or ``const char *`` ---which is one reason why the standard
196 ``string`` class requires you to call the ``c_str`` member
197 function. However, any class that returns a pointer to some internal
198 structure is potentially subject to this problem.
199
200 For example, a program may use a function ``strfunc`` that returns
201 ``string`` objects, and another function ``charfunc`` that
202 operates on pointers to ``char`` :
203
204 .. code-block:: c++
205
206 string strfunc ();
207 void charfunc (const char *);
208
209 void
210 f ()
211 {
212 const char *p = strfunc().c_str();
213 ...
214 charfunc (p);
215 ...
216 charfunc (p);
217 }
218
219 In this situation, it may seem reasonable to save a pointer to the C
220 string returned by the ``c_str`` member function and use that rather
221 than call ``c_str`` repeatedly. However, the temporary string
222 created by the call to ``strfunc`` is destroyed after ``p`` is
223 initialized, at which point ``p`` is left pointing to freed memory.
224
225 Code like this may run successfully under some other compilers,
226 particularly obsolete cfront-based compilers that delete temporaries
227 along with normal local variables. However, the GNU C++ behavior is
228 standard-conforming, so if your program depends on late destruction of
229 temporaries it is not portable.
230
231 The safe way to write such code is to give the temporary a name, which
232 forces it to remain until the end of the scope of the name. For
233 example:
234
235 .. code-block:: c++
236
237 const string& tmp = strfunc ();
238 charfunc (tmp.c_str ());
239
240 .. _copy-assignment:
241
242 Implicit Copy-Assignment for Virtual Bases
243 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
244
245 When a base class is virtual, only one subobject of the base class
246 belongs to each full object. Also, the constructors and destructors are
247 invoked only once, and called from the most-derived class. However, such
248 objects behave unspecified when being assigned. For example:
249
250 .. code-block:: c++
251
252 struct Base{
253 char *name;
254 Base(const char *n) : name(strdup(n)){}
255 Base& operator= (const Base& other){
256 free (name);
257 name = strdup (other.name);
258 return *this;
259 }
260 };
261
262 struct A:virtual Base{
263 int val;
264 A():Base("A"){}
265 };
266
267 struct B:virtual Base{
268 int bval;
269 B():Base("B"){}
270 };
271
272 struct Derived:public A, public B{
273 Derived():Base("Derived"){}
274 };
275
276 void func(Derived &d1, Derived &d2)
277 {
278 d1 = d2;
279 }
280
281 The C++ standard specifies that :samp:`Base::Base` is only called once
282 when constructing or copy-constructing a Derived object. It is
283 unspecified whether :samp:`Base::operator=` is called more than once when
284 the implicit copy-assignment for Derived objects is invoked (as it is
285 inside :samp:`func` in the example).
286
287 G++ implements the 'intuitive' algorithm for copy-assignment: assign all
288 direct bases, then assign all members. In that algorithm, the virtual
289 base subobject can be encountered more than once. In the example, copying
290 proceeds in the following order: :samp:`name` (via ``strdup``),
291 :samp:`val`, :samp:`name` again, and :samp:`bval`.
292
293 If application code relies on copy-assignment, a user-defined
294 copy-assignment operator removes any uncertainties. With such an
295 operator, the application can define whether and how the virtual base
296 subobject is assigned.