Topic: override on free-standing functions (compiler error


Author: julien@nanolive.ch
Date: Wed, 12 Sep 2018 01:50:49 -0700 (PDT)
Raw View
------=_Part_1957_2078064836.1536742249522
Content-Type: multipart/alternative;
 boundary="----=_Part_1958_584045642.1536742249522"

------=_Part_1958_584045642.1536742249522
Content-Type: text/plain; charset="UTF-8"

Hi,

From time to time in I have to declare a free-standing function in a header
file and implement it in the corresponding cpp file. Very basic stuff. What
always bothers me though is that when I have a discrepancy in the
signatures (ex. I update the header and forget to update the
implementation) I'm only aware of the problem at linker time. Then it
becomes a hunt to find out why things are not working though it compiles
fine.

In such cases I'm always tempted to create a static member function to get
a compilation error instead. But that feels like more overhead than
necessary.

My idea would be to allow the keyword "override" in the implementation to
make the compiler aware the function must have been pre-declared. Otherwise
a compilation error is generated which makes it much easier to find the
problem than a linker error. *Note: I chose "override" as it's an existing
keyword that seems semantically closest to what I propose, but maybe there
is a better one.*

What do you think of it?

Example code:

// foo.h

void bar(int&);

struct Foo {
    static void bar(int&);
};

// foo.cpp
#include "foo.h"

// Current - Compiler error: overloaded member function not found
void Foo::bar(int a) { /*...*/ }

// Current - Linker error: unresolved external symbol bar(int&)
void bar(int a) { /*...*/ }

// Proposal - Compiler error: cannot find function pre-declaration.
// Including foo.h may be necessary for this to work (?); but most of the
time it would be done anyway.
void bar(int a) override { /*...*/ }

// main.cpp
#include "foo.h"

int main(int argc, char* argv[])
{
    bar(3);
    Foo::bar(3);
}

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/fa8b3288-c9f8-4f40-b219-1d1e0bb21b2f%40isocpp.org.

------=_Part_1958_584045642.1536742249522
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hi,<br></div><div><br></div><div>From time to time in=
 I have to declare a free-standing function in a header file and implement =
it in the corresponding cpp file. Very basic stuff. What always bothers me =
though is that when I have a discrepancy in the signatures (ex. I update th=
e header and forget to update the implementation) I&#39;m only aware of the=
 problem at linker time. Then it becomes a hunt to find out why things are =
not working though it compiles fine.</div><div><br></div><div>In such cases=
 I&#39;m always tempted to create a static member function to get a compila=
tion error instead. But that feels like more overhead than necessary.</div>=
<div><br></div><div>My idea would be to allow the keyword &quot;override&qu=
ot; in the implementation to make the compiler aware the function must have=
 been pre-declared. Otherwise a compilation error is generated which makes =
it much easier to find the problem than a linker error. <i>Note: I chose &q=
uot;override&quot; as it&#39;s an existing keyword that seems semantically =
closest to what I propose, but maybe there is a better one.</i></div><div><=
br></div><div>What do you think of it?</div><div><br></div><div>Example cod=
e:<br></div><div><br></div><div class=3D"prettyprint" style=3D"background-c=
olor: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: s=
olid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint=
"><div class=3D"subprettyprint"><span style=3D"color: #800;" class=3D"style=
d-by-prettify">// foo.h</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">void</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> bar</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #606;" class=3D"styled-by-prettify">Foo</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">static</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">void</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> bar</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">};</span></div></code></di=
v><div><br></div><div class=3D"prettyprint" style=3D"background-color: rgb(=
250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bord=
er-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span style=3D"color: #800;" class=3D"styled-by-prett=
ify">// foo.cpp</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">#=
include</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;foo.h&=
quot;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// Curr=
ent - Compiler error: overloaded member function not found</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" cl=
ass=3D"styled-by-prettify">Foo</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">bar</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"=
styled-by-prettify">/*...*/</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =
Current - Linker error: unresolved external symbol bar(int&amp;)</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> bar</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #800;" class=3D"styled-by-prettify">/*...*/</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #800;" c=
lass=3D"styled-by-prettify">// Proposal - Compiler error: cannot find funct=
ion pre-declaration.</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #800;" class=3D"styled-by-pretti=
fy">// Including foo.h may be necessary for this to work (?); but most of t=
he time it would be done anyway.</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> bar</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">override</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">/*...*/</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}<=
/span></div></code></div><div><br></div><div class=3D"prettyprint" style=3D=
"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bo=
rder-style: solid; border-width: 1px; word-wrap: break-word;"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">// main.cpp</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" clas=
s=3D"styled-by-prettify">#include</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">&quot;foo.h&quot;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> main</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> arg=
c</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">char</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> argv</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">[])</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 bar</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">3</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>Foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">bar</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">3</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span></div></code></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/fa8b3288-c9f8-4f40-b219-1d1e0bb21b2f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/fa8b3288-c9f8-4f40-b219-1d1e0bb21b2f=
%40isocpp.org</a>.<br />

------=_Part_1958_584045642.1536742249522--

------=_Part_1957_2078064836.1536742249522--

.