Global objects in x3

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Global objects in x3

Orient
Boost.Spirit X3 widely uses global functional objects to define almost anything. Recently I read the article http://ericniebler.github.io/std/wg21/D4381.html and find out, that there is possibility of one definition rule violations for such an objects. I tested it my to dispel my suspicions:
// a.cpp
#include <iostream>
#include <boost/spirit/home/x3.hpp>
void f() { std::cout << &boost::spirit::x3::no_case << std::endl; }
// b.cpp
#include <iostream>
#include <boost/spirit/home/x3.hpp>
void g() { std::cout << &boost::spirit::x3::no_case << std::endl; }
// main.cpp
extern void f();
extern void g();
int main() { f(); g(); return 0; }
// clang++-libc++ -std=gnu++1z -O0 h1.cpp h2.cpp main.cpp -o ./test
typical output:
0x4013a0
0x4013a1
I know there is hard to imagine a case, when it matters much, but library code must be correct at any point of view.
Is there a need to introduce static_const machinery in x3 to avoid mentioned problem?
Reply | Threaded
Open this post in threaded view
|

Re: Global objects in x3

Joel de Guzman
On 5/20/15 12:55 PM, Orient wrote:
> Boost.Spirit X3 widely uses global functional objects to define almost
> anything. Recently I read the article

What exactly do you mean by global functional objects?
The examples you have below are not functional objects.

> http://ericniebler.github.io/std/wg21/D4381.html and find out, that there is
> possibility of one definition rule violations for such an objects. I tested
> it my to dispel my suspicions:
> // a.cpp
> #include <iostream>
> #include <boost/spirit/home/x3.hpp>
> void f() { std::cout << &boost::spirit::x3::no_case << std::endl; }
> // b.cpp
> #include <iostream>
> #include <boost/spirit/home/x3.hpp>
> void g() { std::cout << &boost::spirit::x3::no_case << std::endl; }
> // main.cpp
> extern void f();
> extern void g();
> int main() { f(); g(); return 0; }
> // clang++-libc++ -std=gnu++1z -O0 h1.cpp h2.cpp main.cpp -o ./test
> typical output:
> 0x4013a0
> 0x4013a1
> I know there is hard to imagine a case, when it matters much, but library
> code must be correct at any point of view.
> Is there a need to introduce static_const machinery in x3 to avoid mentioned
> problem?

There are a couple of ways around that that I know of:
1) Make it inline 2) Make it a template. The second is what Spirit
does. But I may be misunderstanding your concern.

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Global objects in x3

Orient
We are talking about variables. So, what does you mean under the `1) Make it inline`? Member functions defined into the class body is inline by default - it is clear there is no odr violations.
namespace boost { namespace spirit { namespace x3
{
no_case_tag const no_case_compare_ = no_case_tag();
}}}

It is global variable.
Reply | Threaded
Open this post in threaded view
|

Re: Global objects in x3

Orient
In reply to this post by Joel de Guzman
I miss "What exactly do you mean by global functional objects?  The examples you have below are not functional objects. ": Yes, not functional objects (they defines operator [], not operator () — it not matters here), but still global variables, that makes odr violation.
Reply | Threaded
Open this post in threaded view
|

Re: Global objects in x3

Joel de Guzman
In reply to this post by Orient
On 5/20/15 1:16 PM, Orient wrote:
> We are talking about variables. So, what does you mean under the `1) Make it
> inline`? Member functions defined into the class body is inline by default -
> it is clear there is no odr violations.
> namespace boost { namespace spirit { namespace x3
> {
> no_case_tag const no_case_compare_ = no_case_tag();
> }}}
>
> It is global variable.

Ah that's not a problem. It's const and it's a POD. There's no
ODR violation in such a case. Constant objects are static by default.

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Global objects in x3

TONGARI J
2015-05-20 16:43 GMT+08:00 Joel de Guzman <[hidden email]>:
On 5/20/15 1:16 PM, Orient wrote:
> We are talking about variables. So, what does you mean under the `1) Make it
> inline`? Member functions defined into the class body is inline by default -
> it is clear there is no odr violations.
> namespace boost { namespace spirit { namespace x3
> {
> no_case_tag const no_case_compare_ = no_case_tag();
> }}}
>
> It is global variable.

Ah that's not a problem. It's const and it's a POD. There's no
ODR violation in such a case. Constant objects are static by default.

It's still ODR violation as long as the variable is odr-used (i.e. the address is taken / a reference is bound to it, including forwarding reference) in different TUs:

Though it might not be a problem in practice.

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Global objects in x3

Joel de Guzman
On 5/20/15 5:05 PM, TONGARI J wrote:

> 2015-05-20 16:43 GMT+08:00 Joel de Guzman <[hidden email] <mailto:[hidden email]>>:
>
>     On 5/20/15 1:16 PM, Orient wrote:
>     > We are talking about variables. So, what does you mean under the `1) Make it
>     > inline`? Member functions defined into the class body is inline by default -
>     > it is clear there is no odr violations.
>     > namespace boost { namespace spirit { namespace x3
>     > {
>     > no_case_tag const no_case_compare_ = no_case_tag();
>     > }}}
>     >
>     > It is global variable.
>
>     Ah that's not a problem. It's const and it's a POD. There's no
>     ODR violation in such a case. Constant objects are static by default.
>
>
> It's still ODR violation as long as the variable is odr-used (i.e. the address is taken /
> a reference is bound to it, including forwarding reference) in different TUs:
> http://en.cppreference.com/w/cpp/language/definition#ODR-use
>
> Though it might not be a problem in practice.

Yes, it's not a problem in practice, but I see your and Orient's point.
I'll study Eric's solution to this problem and apply them to X3.
Thanks for the info, Orient.

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Global objects in x3

Agustín K-ballo Bergé
In reply to this post by TONGARI J
On 5/20/2015 4:05 AM, TONGARI J wrote:

> 2015-05-20 16:43 GMT+08:00 Joel de Guzman <[hidden email]
> <mailto:[hidden email]>>:
>
>     On 5/20/15 1:16 PM, Orient wrote:
>     > We are talking about variables. So, what does you mean under the `1) Make it
>     > inline`? Member functions defined into the class body is inline by default -
>     > it is clear there is no odr violations.
>     > namespace boost { namespace spirit { namespace x3
>     > {
>     > no_case_tag const no_case_compare_ = no_case_tag();
>     > }}}
>     >
>     > It is global variable.
>
>     Ah that's not a problem. It's const and it's a POD. There's no
>     ODR violation in such a case. Constant objects are static by default.
>
>
> It's still ODR violation as long as the variable is odr-used (i.e. the
> address is taken / a reference is bound to it, including forwarding
> reference) in different TUs:
> http://en.cppreference.com/w/cpp/language/definition#ODR-use

IIRC const implies internal linkage (in C++, unlike C) so it's not an
ODR violation.

Regards,
--
Agustín K-ballo Bergé.-
http://talesofcpp.fusionfenix.com

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Global objects in x3

TONGARI J
2015-05-21 2:28 GMT+08:00 Agustín K-ballo Bergé <[hidden email]>:
On 5/20/2015 4:05 AM, TONGARI J wrote:
> 2015-05-20 16:43 GMT+08:00 Joel de Guzman <[hidden email]
> <mailto:[hidden email]>>:
>
>     On 5/20/15 1:16 PM, Orient wrote:
>     > We are talking about variables. So, what does you mean under the `1) Make it
>     > inline`? Member functions defined into the class body is inline by default -
>     > it is clear there is no odr violations.
>     > namespace boost { namespace spirit { namespace x3
>     > {
>     > no_case_tag const no_case_compare_ = no_case_tag();
>     > }}}
>     >
>     > It is global variable.
>
>     Ah that's not a problem. It's const and it's a POD. There's no
>     ODR violation in such a case. Constant objects are static by default.
>
>
> It's still ODR violation as long as the variable is odr-used (i.e. the
> address is taken / a reference is bound to it, including forwarding
> reference) in different TUs:
> http://en.cppreference.com/w/cpp/language/definition#ODR-use

IIRC const implies internal linkage (in C++, unlike C) so it's not an
ODR violation.

Well, I hope Eric is wrong:

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Global objects in x3

Lee Clagett-2


On Wed, May 20, 2015 at 9:11 PM, TONGARI J <[hidden email]> wrote:
2015-05-21 2:28 GMT+08:00 Agustín K-ballo Bergé <[hidden email]>:
On 5/20/2015 4:05 AM, TONGARI J wrote:
> 2015-05-20 16:43 GMT+08:00 Joel de Guzman <[hidden email]
> <mailto:[hidden email]>>:
>
>     On 5/20/15 1:16 PM, Orient wrote:
>     > We are talking about variables. So, what does you mean under the `1) Make it
>     > inline`? Member functions defined into the class body is inline by default -
>     > it is clear there is no odr violations.
>     > namespace boost { namespace spirit { namespace x3
>     > {
>     > no_case_tag const no_case_compare_ = no_case_tag();
>     > }}}
>     >
>     > It is global variable.
>
>     Ah that's not a problem. It's const and it's a POD. There's no
>     ODR violation in such a case. Constant objects are static by default.
>
>
> It's still ODR violation as long as the variable is odr-used (i.e. the
> address is taken / a reference is bound to it, including forwarding
> reference) in different TUs:
> http://en.cppreference.com/w/cpp/language/definition#ODR-use

IIRC const implies internal linkage (in C++, unlike C) so it's not an
ODR violation.

Well, I hope Eric is wrong:


I think Eric is correct. From 3.2.4 of draft N3797:

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used
in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found
in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see
12.1, 12.4 and 12.8). An inline function shall be defined in every translation unit in which it is odr-used.

So I _think_ it is an ODR violation if the address of the variable is taken (ODR-used). The internal linkage is simply masking the ODR violation - no diagnostic is necessary, as per the standard.

But does it matter? Has this been an issue in the past? This is a significant amount of work, and the use case for the "function object" is much different than the one Eric is describing.

Lee


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Global objects in x3

Joel de Guzman
On 5/21/15 9:29 AM, Lee Clagett wrote:

>
>
> On Wed, May 20, 2015 at 9:11 PM, TONGARI J <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     2015-05-21 2:28 GMT+08:00 Agustín K-ballo Bergé <[hidden email]
>     <mailto:[hidden email]>>:
>
>         On 5/20/2015 4:05 AM, TONGARI J wrote:
>         > 2015-05-20 16:43 GMT+08:00 Joel de Guzman <[hidden email] <mailto:[hidden email]>
>         > <mailto:[hidden email] <mailto:[hidden email]>>>:
>         >
>         >     On 5/20/15 1:16 PM, Orient wrote:
>         >     > We are talking about variables. So, what does you mean under the `1) Make it
>         >     > inline`? Member functions defined into the class body is inline by default -
>         >     > it is clear there is no odr violations.
>         >     > namespace boost { namespace spirit { namespace x3
>         >     > {
>         >     > no_case_tag const no_case_compare_ = no_case_tag();
>         >     > }}}
>         >     >
>         >     > It is global variable.
>         >
>         >     Ah that's not a problem. It's const and it's a POD. There's no
>         >     ODR violation in such a case. Constant objects are static by default.
>         >
>         >
>         > It's still ODR violation as long as the variable is odr-used (i.e. the
>         > address is taken / a reference is bound to it, including forwarding
>         > reference) in different TUs:
>         >http://en.cppreference.com/w/cpp/language/definition#ODR-use
>
>         IIRC const implies internal linkage (in C++, unlike C) so it's not an
>         ODR violation.
>
>
>     Well, I hope Eric is wrong:
>     http://ericniebler.github.io/std/wg21/D4381.html#no-violations-of-the-one-definition-rule
>
>
> I think Eric is correct. From 3.2.4 of draft N3797:
>
> Every program shall contain exactly one definition of every non-inline function or
> variable that is odr-used
> in that program; no diagnostic required. The definition can appear explicitly in the
> program, it can be found
> in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see
> 12.1, 12.4 and 12.8). An inline function shall be defined in every translation unit in
> which it is odr-used.
>
> So I _think_ it is an ODR violation if the address of the variable is taken (ODR-used).
> The internal linkage is simply masking the ODR violation - no diagnostic is necessary, as
> per the standard.
>
> But does it matter? Has this been an issue in the past? This is a significant amount of
> work, and the use case for the "function object" is much different than the one Eric is
> describing.

Yup. I studied the issue a bit more. So it happens that if the address is taken
in two or more TUs, then there's ODR and there (ought to be) a linker error.
For instance, if the parse functions do take in the parsers (and skippers) by
const reference (e.g.):

   Skipper const& s

So therefore, pedantically speaking, if we pass space, we have ODR violation since
its address is taken and it becomes "ODR-used".

Does it matter? I haven't experienced any problem such as linker errors so far.
I can't tell if it's a real problem or not. But that does not mean that this
will not bite us in the end (somehow).

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general