473,503 Members | 3,884 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

question on c++ constants?

Dear All,

I am always confused in using constants in multiple files.

For global constants, I got some clues from
http://msdn.microsoft.com/en-us/libr...2d(VS.80).aspx

So in header file writing: const double PI = 3.14;
Every time using it, include the header file.

But how about constants in namespaces and classes?

Thanks for your help!

Shuisheng
Oct 14 '08
54 3547
On Oct 16, 9:25 pm, Gennaro Prota <gennaro/pr...@yahoo.comwrote:
gpderetta wrote:
It is not just a matter of types, consider this:
// in foo.hpp
struct my_functor_type {...};
namespace { my_functor_type bar; }
template<class Tvoid foo(T x) {
bar(x);
}
Now, if foo is instantiated in two translation units with
the same T, it will lead to ODR violation.
Do you mean that there's no violation if you instantiate on
different T's?
Not in this case. It's being used in a dependent context, so
name binding doesn't occur until instantiation. The applicable
part is the last couple of sentences in §14.6.4.1: "A
specialization for any template may have points of instantiation
in multiple translation units. If two different points of
instantiation give a template specialization different meanings
according to the one definition rule, the program is ill-formed,
no diagnostic required." (Which seems to be a contradiction in
itself: ill-formed means that a diagnostic is required,
otherwise, it's undefined behavior.)
This is not a made up example, I often find the need to name
function object instances in header files,
Out of curiosity, why?
Because it gives an excuse to use more templates:-).

The cases where you need a non-local instance at all are
probably very, very rare. But even then, C++ supports global
variables very well, and if you really need headers only---say
because you've imposed a really broken build system---then
there's always the classical and universally known inline
function returning a reference to a local static idiom.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Oct 17 '08 #51
James Kanze wrote:
On Oct 16, 9:25 pm, Gennaro Prota <gennaro/pr...@yahoo.comwrote:
>gpderetta wrote:
>>It is not just a matter of types, consider this:
>>// in foo.hpp
struct my_functor_type {...};
>> namespace { my_functor_type bar; }
>> template<class Tvoid foo(T x) {
bar(x);
}
>>Now, if foo is instantiated in two translation units with
the same T, it will lead to ODR violation.
>Do you mean that there's no violation if you instantiate on
different T's?

Not in this case. It's being used in a dependent context, so
name binding doesn't occur until instantiation. The applicable
part is the last couple of sentences in §14.6.4.1: "A
specialization for any template may have points of instantiation
in multiple translation units. If two different points of
instantiation give a template specialization different meanings
according to the one definition rule, the program is ill-formed,
no diagnostic required."
Ah, right. So 3.2 [basic.def.odr] p5:

in each definition of D, corresponding names, looked up
according to 3.4, shall refer to an entity defined within the
definition of D, or shall refer to the same entity, after
overload resolution (13.3) and after matching of partial
template specialization (14.8.3) [...]

must first be applied with D being the function template, just
to be pointed to 3.4; then (once back from 3.4, which leads to
14.6.4.1) again with D being each function template
instantiation (i.e. each template function).

But here we have just one name in the body of foo (ignoring the
trivial case of 'x'). If we have several, some being dependent
and some non-dependent, how is 3.2 to be interpreted? Shall
*all* non-dependent names resolve to the same entity in the
context of the template *definition*?
(Which seems to be a contradiction in
itself: ill-formed means that a diagnostic is required,
otherwise, it's undefined behavior.)
This isn't the only usage of "ill-formed, with no diagnostic
required". Another one we came upon recently is the case in
which no valid specialization of a template can be generated:
the template definition is ill-formed (and, so, the whole
program?) and no diagnostic is required:

template< typename T >
void f()
{
1 / ( sizeof( T ) == 0 ) ;
}

template< typename T >
void f()
{
static_assert( sizeof( T ) == 0, "" ) ;
}

It remains a bit unclear to me what does it concretely mean for
a template definition to be ill-formed when it is never
instantiated. Among other things:

* AFAICS, "ill-formed" applies to (is defined for) a program.
When the standard says the template definition is
ill-formed, does it mean that the program which contains it
is ill-formed?

* According to 1.4 [intro.compliance] bullet 3, it seems that
a program containing such a template definition invokes UB.
But is that the intent? It seems a bit over the top.

(Incidentally, there's also another point about terminology:
"diagnosable rule" suggests "rule that *may* be diagnosed", not
that "must be diagnosed". This example is about a rule which may
be diagnosed, but isn't diagnosable :-))

--
Gennaro Prota | name.surname yahoo.com
Breeze C++ (preview): <https://sourceforge.net/projects/breeze/>
Do you need expertise in C++? I'm available.
Oct 18 '08 #52
On Oct 17, 3:28 pm, James Kanze <james.ka...@gmail.comwrote:
On Oct 16, 6:58 pm, gpderetta <gpdere...@gmail.comwrote:
This is not a made up example, I often find the need to name
function object instances in header files, but, if the
anonymous namespace is dropped, you will get multiple
definitions for 'bar'. The only workaround I know (from the
boost mailing list) is:
template <class Fstruct instance_of { static T value; };
template<class TT instance_of<T>::value = {}
namespace { my_functor_type const& bar =
instance_of<my_functor_type>::value; }
template<class Tvoid foo(T x) {
bar(x);
}

Typical Boost:-). Why do simple when you can do complicated:

namespace Whatever_Private
{
extern my_functor_type bar ;
} ;
That's the best solution of course. But see at the end.
Or if you really need to be headers only:

namespace Whatever_Private
{
inline my_functor_type& bar()
{
static my_functor_type theOneAndOnly ;
return theOneAndOnly ;
}
} ;
Well, as my function objects are stateless 99% of the times, if I have
to use an extra set of (), I might as well just instantiate the
function object on the fly. The idea is to use the same syntax for
function objects and functions (i.e. the user doesn't really need to
know if a certain function is really a function or a function object,
up to a point of course).
Now there won't be any ODR violations in 'foo', if the ODR
rule is interpret as only requiring all symbols to bind to the
same objects in all translation units.

If you want the library to be headers only, then you need to
encapsulate the definition in something which can appear in
multiple compilation units: a template or an inline function.
Generally, you're better off dropping the headers only
requirement, however.
Often, at least in my code, function objects are compile time
polymorphic (i.e. they have a templated operator(); in fact if it is
not polymorphic there is little need to define a function object in
the first place), so you have to define them in the header anyway.
Having a .cc file just to contain their instantiation is just ugly. I
should probably write a tool that generate such .cc files on the fly
and just add it to the build system.

--
gpd
Oct 18 '08 #53
On Oct 18, 11:52*am, Gennaro Prota <gennaro/pr...@yahoo.comwrote:
James Kanze wrote:
On Oct 16, 9:25 pm, Gennaro Prota <gennaro/pr...@yahoo.comwrote:
gpderetta wrote:
It is not just a matter of types, consider this:
>// in foo.hpp
* struct my_functor_type {...};
>* namespace { my_functor_type bar; }
>* template<class Tvoid foo(T x) {
* * *bar(x);
* }
>Now, if foo is instantiated in two translation units with
the same T, it will lead to ODR violation.
Do you mean that there's no violation if you instantiate on
different T's?
Not in this case. *It's being used in a dependent context, so
name binding doesn't occur until instantiation. *The applicable
part is the last couple of sentences in §14.6.4.1: "A
specialization for any template may have points of instantiation
in multiple translation units. *If two different points of
instantiation give a template specialization different meanings
according to the one definition rule, the program is ill-formed,
no diagnostic required."
Ah, right. So 3.2 [basic.def.odr] p5:
* *in each definition of D, corresponding names, looked up
* *according to 3.4, shall refer to an entity defined within the
* *definition of D, or shall refer to the same entity, after
* *overload resolution (13.3) and after matching of partial
* *template specialization (14.8.3) [...]
must first be applied with D being the function template, just
to be pointed to 3.4;
Not at all. Note the "looked up" in the above paragraph. Names
in a dependent context are not looked up until the template is
instantiated, in the context of the instantiation. (In some
cases, there will be restrictions along the lines that bar may
not be/must be a type or a template, but I don't think any of
those apply here.)
then (once back from 3.4, which leads to
14.6.4.1) again with D being each function template
instantiation (i.e. each template function).
But here we have just one name in the body of foo (ignoring
the trivial case of 'x'). If we have several, some being
dependent and some non-dependent, how is 3.2 to be
interpreted?
Every name to be looked up is either dependent or not. This is
all spelled out in §14.6, and particularly in §14.6.2: in a
function call where the name of the function is an unqualified
id, the name of the function is dependent if and only if any of
the arguments is a type-dependent expression.
Shall *all* non-dependent names resolve to the same entity in
the context of the template *definition*?
All names looked up in a non-dependent context must resolve to
the same entity at the point of the template definition. (Names
in a dependent context aren't looked up until instantiation.
There's some added confusion because at instantiation time,
names will also be looked up in the context of the template
defintion.)
(Which seems to be a contradiction in itself: ill-formed
means that a diagnostic is required, otherwise, it's
undefined behavior.)
This isn't the only usage of "ill-formed, with no diagnostic
required".
Probably not. The standard isn't always as coherent in its use
of words as it should be. As it happens, the standard is far
more explicit, and defines violations of the one definition rule
as an explicit exception to the "requiring a diagnostic", see
below.
Another one we came upon recently is the case in which no
valid specialization of a template can be generated: the
template definition is ill-formed (and, so, the whole
program?) and no diagnostic is required:
* *template< typename T >
* *void f()
* *{
* * *1 / ( sizeof( T ) == 0 ) ;
* *}
* *template< typename T >
* *void f()
* *{
* * *static_assert( sizeof( T ) == 0, "" ) ;
* *}
It remains a bit unclear to me what does it concretely mean
for a template definition to be ill-formed when it is never
instantiated.
I don't see how you can get any ill-formedness here without
instantiation. I have no idea how static_assert works, so I
can't be sure there, but in both cases, all of the expressions
are dependent, so analysis won't (and can't) really take place
until instantiation. In particular, although we know that
sizeof(T) can never be less than 1, I don't think that the
compiler can do anything more than a simple syntax check here
until instantiation. Although not an issue directly addressed
by the standard, for example, if T is void or a function or an
incomplete type, the compiler will probably not want to issue
the same diagnosic as it would if T where a complete data type.
I think the compiler requires the first f() to compile, as long
as there is no instantiation (and will require a diagnostic for
all instantations, either because you're taking sizeof of
something which isn't a legal operand of sizeof, or because
you're dividing by zero in an integral constant expression).
Among other things:
* ** AFAICS, "ill-formed" applies to (is defined for) a program.
* * *When the standard says the template definition is
* * *ill-formed, does it mean that the program which contains it
* * *is ill-formed?
Ill-formed applies, first and foremost, to syntax, in its
largest sense. (In any real sense, the fact that the number and
types of the arguments in a function call must agree with the
number and types of the paramters in the declaration is syntax,
in the same way as the fact that the number and gender of an
adjective in French or Italian must agree with the noun it
modifies is syntax.) And requires a compile time diagnostic.
That's what I would expect. The C++ standard defines things
slightly differently, however: an ill-formed program is one that
isn't well-formed, and a well-formed program is "a C++ program
constructed according to the syntax rules, diagnosable semantic
rules, and the One Definition Rule." In other words, violations
of the one definition rule are an explicit exception to the rule
that "ill-formed" requires a diagnostic.

And template definitions, or whatever, aren't ill-formed.
Programs are ill-formed. (Of course, it may be the presence of
a specific definition which renders it ill-formed.)
* ** According to 1.4 [intro.compliance] bullet 3, it seems that
* * *a program containing such a template definition invokes UB.
* * *But is that the intent? It seems a bit over the top.
(Incidentally, there's also another point about terminology:
"diagnosable rule" suggests "rule that *may* be diagnosed",
not that "must be diagnosed". This example is about a rule
which may be diagnosed, but isn't diagnosable :-))
Again, the standard defines its own language, to a degree.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Oct 19 '08 #54
James Kanze wrote:
On Oct 18, 11:52 am, Gennaro Prota <gennaro/pr...@yahoo.comwrote:
>James Kanze wrote:
>>On Oct 16, 9:25 pm, Gennaro Prota <gennaro/pr...@yahoo.comwrote:
gpderetta wrote:
It is not just a matter of types, consider this:
>>>>// in foo.hpp
struct my_functor_type {...};
>>>> namespace { my_functor_type bar; }
>>>> template<class Tvoid foo(T x) {
bar(x);
}
>>>>Now, if foo is instantiated in two translation units with
the same T, it will lead to ODR violation.
>>>Do you mean that there's no violation if you instantiate on
different T's?
>>Not in this case. It's being used in a dependent context, so
name binding doesn't occur until instantiation. The applicable
part is the last couple of sentences in §14.6.4.1: "A
specialization for any template may have points of instantiation
in multiple translation units. If two different points of
instantiation give a template specialization different meanings
according to the one definition rule, the program is ill-formed,
no diagnostic required."
>Ah, right. So 3.2 [basic.def.odr] p5:
> in each definition of D, corresponding names, looked up
according to 3.4, shall refer to an entity defined within the
definition of D, or shall refer to the same entity, after
overload resolution (13.3) and after matching of partial
template specialization (14.8.3) [...]
>must first be applied with D being the function template, just
to be pointed to 3.4;

Not at all. Note the "looked up" in the above paragraph. Names
in a dependent context are not looked up until the template is
instantiated, in the context of the instantiation.
I meant "applied" by the reader of the standard, not by the
compiler. That is: you consult 3.2 to see if the template
definition violates the ODR; 3.2 refers you to clause 14 (for
the template definition). Then clause 14 refers you back to 3.2
for each template instantation. Not sure I managed to explain it
:-)
(In some
cases, there will be restrictions along the lines that bar may
not be/must be a type or a template, but I don't think any of
those apply here.)
>then (once back from 3.4, which leads to
14.6.4.1) again with D being each function template
instantiation (i.e. each template function).
>But here we have just one name in the body of foo (ignoring
the trivial case of 'x'). If we have several, some being
dependent and some non-dependent, how is 3.2 to be
interpreted?

Every name to be looked up is either dependent or not. This is
all spelled out in §14.6, and particularly in §14.6.2: in a
function call where the name of the function is an unqualified
id, the name of the function is dependent if and only if any of
the arguments is a type-dependent expression.
>Shall *all* non-dependent names resolve to the same entity in
the context of the template *definition*?

All names looked up in a non-dependent context must resolve to
the same entity at the point of the template definition. (Names
in a dependent context aren't looked up until instantiation.
There's some added confusion because [...snip]
This is a very important "detail": if *one* dependent usage were
enough to postpone all the lookup to instantiation time then
things would be simpler. Instead, each non-dependent name must
bind uniquely, at definition. Which means that as soon as you
have e.g. bar( 5 )...

Which brings us to the initial point... here you have or not an
ODR violation, depending on the arguments to bar, not just on
its definition: it leads to *easily* to a violation.
>>(Which seems to be a contradiction in itself: ill-formed
means that a diagnostic is required, otherwise, it's
undefined behavior.)
>This isn't the only usage of "ill-formed, with no diagnostic
required".

Probably not. The standard isn't always as coherent in its use
of words as it should be. As it happens, the standard is far
more explicit, and defines violations of the one definition rule
as an explicit exception to the "requiring a diagnostic", see
below.
>Another one we came upon recently is the case in which no
valid specialization of a template can be generated: the
template definition is ill-formed (and, so, the whole
program?) and no diagnostic is required:
> template< typename T >
void f()
{
1 / ( sizeof( T ) == 0 ) ;
}
> template< typename T >
void f()
{
static_assert( sizeof( T ) == 0, "" ) ;
}
>It remains a bit unclear to me what does it concretely mean
for a template definition to be ill-formed when it is never
instantiated.

I don't see how you can get any ill-formedness here without
instantiation.
Well, the standard says it is ill-formed, instantiated or not. I
said we came upon it recently, but I forgot that it was on
c++.moderated and you didn't get involved. FWIW, the thread is:
<http://google.com/group/comp.lang.c++.moderated/browse_frm/thread/332821427ddca414/0ebc2af6ee0e2f2a>

The relevant wording is in 14.6 [temp.res]:

If no valid specialization can be generated for a template
definition, and that template is not instantiated, the tem-
plate definition is ill-formed, no diagnostic required.

The fact that this is in a section about name resolution makes
one wonder whether it is meant to be applied in all its
generality (anything which doesn't have at least one well-formed
specialization is ill-formed) or just for name issues. In the
example with static_assert there's in fact no name other than T
(off the top of my head I think static_assert declarations and
asm declarations are the only "declarations" which don't declare
a name).

Well, one of the EDG guys (whom I'll not mention because I
haven't asked for his permission to) clarified, privately, that
it was the intent for both examples to be ill-formed. About the
possibility of diagnosing it I don't know... an idea --specific
to these two examples-- might be to have something like an
implicit 'has_size' concept, used internally by the compiler
(not explicitly spelled out by the programmer).

[...]
>Among other things:
> * AFAICS, "ill-formed" applies to (is defined for) a program.
When the standard says the template definition is
ill-formed, does it mean that the program which contains it
is ill-formed?
[...]
And template definitions, or whatever, aren't ill-formed.
Programs are ill-formed. (Of course, it may be the presence of
a specific definition which renders it ill-formed.)
That was my point. And making a whole program invoke UB because
it has an "invalid" template definition which is never
instantiated looks like an exaggeration.
> * According to 1.4 [intro.compliance] bullet 3, it seems that
a program containing such a template definition invokes UB.
But is that the intent? It seems a bit over the top.
>(Incidentally, there's also another point about terminology:
"diagnosable rule" suggests "rule that *may* be diagnosed",
not that "must be diagnosed". This example is about a rule
which may be diagnosed, but isn't diagnosable :-))

Again, the standard defines its own language, to a degree.
The principle of least astonishment at work, that is.

--
Gennaro Prota | name.surname yahoo.com
Breeze C++ (preview): <https://sourceforge.net/projects/breeze/>
Do you need expertise in C++? I'm available.
Oct 22 '08 #55

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1201
by: Sugapablo | last post by:
I'm trying to use the Const statement to define a group of constants. I would like different groups of constants, one for each language (such as english, spanish, etc.) Depending on a variable...
4
2554
by: gabriel | last post by:
Greetings, I am working on a project and cannot choose the best way to achieve this : I got a method which returns an error code like this : DISK_FULL or PERMISSION_DENIED. Those are...
13
3042
by: poison.summer | last post by:
Hello If I have an enum definition for instance typedef enum { F0 = 0, F1 = 1, F2 = 2, F3 =3
2
1795
by: yawnmoth | last post by:
The PHP license states the following: 4. Products derived from this software may not be called "PHP", nor may "PHP" appear in their name, without prior written permission from group@php.net. ...
4
1992
by: D. Yates | last post by:
Hi all, Is there a place in the .NET framework where simple time constants are defined? For example: How many days are there in a week? Hours in a day? Minutes in an hour? Seconds in a...
10
1558
by: Steven W. Orr | last post by:
I saw this and tried to use it: ------------------><8------------------- const.py------------- class _const: class ConstError(TypeError): pass def __setattr__(self,name,value): if...
3
1247
by: Steven W. Orr | last post by:
This is all an intro learning experience for me, so please feel free to explain why what I'm trying to do is not a good idea. In the Cookbook, they have a recipe for how to create global...
6
1619
by: lazy | last post by:
hi, I have some constants defined in a php script say config.php. I want to use the variables there defined in other scripts. couple of questions regd that: 1. Is there an alternative to...
3
1666
by: Microsoft | last post by:
Hi I have a c# program that continually runs 24/7 and performs a variety of tasks based on a timer. There is one routine that hangs every Saturday morning without fail. If I restart the...
0
7258
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7313
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6970
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5558
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4663
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3156
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3146
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
720
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
366
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.