Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #8041 > unrolled thread

#define - in header or cpp

Started byChristopher <cpisz@austin.rr.com>
First post2011-07-21 08:11 -0700
Last post2011-07-26 16:14 +0000
Articles 20 — 11 participants

Back to article view | Back to comp.lang.c++


Contents

  #define - in header or cpp Christopher <cpisz@austin.rr.com> - 2011-07-21 08:11 -0700
    Re: #define - in header or cpp Victor Bazarov <v.bazarov@comcast.invalid> - 2011-07-21 11:27 -0400
    Re: #define - in header or cpp "Balog Pal" <pasa@lib.hu> - 2011-07-21 17:34 +0200
      Re: #define - in header or cpp Christopher <cpisz@austin.rr.com> - 2011-07-21 10:42 -0700
      Re: #define - in header or cpp Paul Brettschneider <paul.brettschneider@yahoo.fr> - 2011-07-21 20:36 +0200
        Re: #define - in header or cpp Victor Bazarov <v.bazarov@comcast.invalid> - 2011-07-21 15:21 -0400
          Re: #define - in header or cpp Paul Brettschneider <paul.brettschneider@yahoo.fr> - 2011-07-21 23:27 +0200
        Re: #define - in header or cpp Ian Collins <ian-news@hotmail.com> - 2011-07-22 09:35 +1200
          Re: #define - in header or cpp Paul Brettschneider <paul.brettschneider@yahoo.fr> - 2011-07-21 23:57 +0200
          Re: #define - in header or cpp Thomas Boell <tboell@domain.invalid> - 2011-07-22 01:06 +0200
            Re: #define - in header or cpp Ian Collins <ian-news@hotmail.com> - 2011-07-22 11:14 +1200
            Re: #define - in header or cpp Paul Brettschneider <paul.brettschneider@yahoo.fr> - 2011-07-22 08:49 +0200
              Re: #define - in header or cpp Joe Greer <jgreer@doubletake.com> - 2011-07-22 13:23 +0000
              Re: #define - in header or cpp James Kanze <james.kanze@gmail.com> - 2011-07-22 12:58 -0700
      Re: #define - in header or cpp James Kanze <james.kanze@gmail.com> - 2011-07-22 12:51 -0700
    Re: #define - in header or cpp gwowen <gwowen@gmail.com> - 2011-07-22 00:29 -0700
      Re: #define - in header or cpp Christopher <cpisz@austin.rr.com> - 2011-07-22 15:56 -0700
    Re: #define - in header or cpp Juha Nieminen <nospam@thanks.invalid> - 2011-07-22 14:33 +0000
      Re: #define - in header or cpp Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-07-26 11:26 +0000
        Re: #define - in header or cpp Juha Nieminen <nospam@thanks.invalid> - 2011-07-26 16:14 +0000

#8041 — #define - in header or cpp

FromChristopher <cpisz@austin.rr.com>
Date2011-07-21 08:11 -0700
Subject#define - in header or cpp
Message-ID<d0a4638c-2b91-4099-8718-cb47ada19e53@h14g2000yqd.googlegroups.com>
I don't use #defines myself, or very rarely. We are in the middle of a
style war and a coding style is being written up. Which brings the
topic of #define in preexisting code.

Obviously, #define directives the header needs will have to go in the
header. But what of all of the #defines that are used like constants?

example
#define MYSILLYSTRING "I'm a String"

When these are only used in a class' .cpp?

Should these go in the .h or the .cpp file? Reasoning?

[toc] | [next] | [standalone]


#8042

FromVictor Bazarov <v.bazarov@comcast.invalid>
Date2011-07-21 11:27 -0400
Message-ID<j09gha$c2p$1@dont-email.me>
In reply to#8041
On 7/21/2011 11:11 AM, Christopher wrote:
> I don't use #defines myself, or very rarely. We are in the middle of a
> style war and a coding style is being written up. Which brings the
> topic of #define in preexisting code.
>
> Obviously, #define directives the header needs will have to go in the
> header. But what of all of the #defines that are used like constants?
>
> example
> #define MYSILLYSTRING "I'm a String"
>
> When these are only used in a class' .cpp?
>
> Should these go in the .h or the .cpp file? Reasoning?

Depends.  If more than one source file uses such macros, they should 
probably stay in *one place* so when there's a need to change the value, 
you'd only go to one place to change it.  The simplest example is some 
kind of *version* designation that might be needed in both C++ and 
*resource* files.

V
-- 
I do not respond to top-posted replies, please don't ask

[toc] | [prev] | [next] | [standalone]


#8043

From"Balog Pal" <pasa@lib.hu>
Date2011-07-21 17:34 +0200
Message-ID<j09gu1$10qq$1@news.ett.com.ua>
In reply to#8041
"Christopher" <cpisz@austin.rr.com>

>I don't use #defines myself, or very rarely. We are in the middle of a
> style war and a coding style is being written up.

Reimplementing the wheel? Isn't the Sutter/Alexandrescu 101 book good enough 
for your place?

> Which brings the
> topic of #define in preexisting code.
>
> Obviously, #define directives the header needs will have to go in the
> header. But what of all of the #defines that are used like constants?
>
> example
> #define MYSILLYSTRING "I'm a String"
>
> When these are only used in a class' .cpp?
>
> Should these go in the .h or the .cpp file? Reasoning?

1. header files are for shared stuff. what must be shared goes there. What 
must not goes elsewhere.
2. #define is just for last resort -- use C++ native stuff wherever 
possible.
3. where you are left with #define name it so it can not be confused with 
anything else, and especially can not replace a part of existing code. 
(like the evil GetMessage macro in windowsx.h)
4. If you have the strudy naming convintion from #3 it is no longer so 
interesting where the macro was defined. So just use #1 for decision
5. use #undef for macros of short intended scope

[toc] | [prev] | [next] | [standalone]


#8047

FromChristopher <cpisz@austin.rr.com>
Date2011-07-21 10:42 -0700
Message-ID<8d714f47-9f08-4dbf-ba4a-74f4677682f1@n35g2000yqf.googlegroups.com>
In reply to#8043
On Jul 21, 10:34 am, "Balog Pal" <p...@lib.hu> wrote:
> "Christopher" <cp...@austin.rr.com>
>
> >I don't use #defines myself, or very rarely. We are in the middle of a
> > style war and a coding style is being written up.
>
> Reimplementing the wheel? Isn't the Sutter/Alexandrescu 101 book good enough
> for your place?

If it was up to me. I just get to give limited input/arguments, if
that.


> > Which brings the
> > topic of #define in preexisting code.
>
> > Obviously, #define directives the header needs will have to go in the
> > header. But what of all of the #defines that are used like constants?
>
> > example
> > #define MYSILLYSTRING "I'm a String"
>
> > When these are only used in a class' .cpp?
>
> > Should these go in the .h or the .cpp file? Reasoning?
>
> 1. header files are for shared stuff. what must be shared goes there. What
> must not goes elsewhere.
> 2. #define is just for last resort -- use C++ native stuff wherever
> possible.
> 3. where you are left with #define name it so it can not be confused with
> anything else, and especially can not replace a part of existing code.
> (like the evil GetMessage macro in windowsx.h)
> 4. If you have the strudy naming convintion from #3 it is no longer so
> interesting where the macro was defined. So just use #1 for decision
> 5. use #undef for macros of short intended scope

Good stuff. Thanks.

[toc] | [prev] | [next] | [standalone]


#8048

FromPaul Brettschneider <paul.brettschneider@yahoo.fr>
Date2011-07-21 20:36 +0200
Message-ID<e0b93$4e28719b$506c0d9c$16489@news.chello.at>
In reply to#8043
Balog Pal wrote:

> 2. #define is just for last resort -- use C++ native stuff wherever
> possible.

Somewhat off-topic: What is the C++-way of implementing string literal 
macros for use with concetenation?

What I mean is this:

#define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
static const char control_sequence[] = "\xde\xad\xbe\xef";
static const char *f1()
{
        return "Test " CONTROL_SEQUENCE " string"; // Compiles but ugly
}
static const char *f2()
{
        return "Test " control_sequence " string"; // Error
}

Thanks.

[toc] | [prev] | [next] | [standalone]


#8053

FromVictor Bazarov <v.bazarov@comcast.invalid>
Date2011-07-21 15:21 -0400
Message-ID<j09u72$cp5$1@dont-email.me>
In reply to#8048
On 7/21/2011 2:36 PM, Paul Brettschneider wrote:
> Balog Pal wrote:
>
>> 2. #define is just for last resort -- use C++ native stuff wherever
>> possible.
>
> Somewhat off-topic: What is the C++-way of implementing string literal
> macros for use with concetenation?

It's a simple text replacement.  There are no "string literal macros".

>
> What I mean is this:
>
> #define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
> static const char control_sequence[] = "\xde\xad\xbe\xef";
> static const char *f1()
> {
>          return "Test " CONTROL_SEQUENCE " string"; // Compiles but ugly

This is converted by the preprocessor into

return "Test " "\xde\xad\xbe\xef" " string";

(whitespace condenced, comments replaced with whitespace, macros are 
replaced with their "values" - straight text substitution), and then the 
adjacent string literals are concatenated (phase 6), so you get

return "Test \xde\xad\xbe\xef string";

just before the compiler gets that list of *tokens*.

> }
> static const char *f2()
> {
>          return "Test " control_sequence " string"; // Error
> }

There is no textual replacement here.  It's a different list of tokens 
the compiler gets:

return "Test " control_sequence " string";

in which no string literal appears in place of 'control_sequence' (which 
is a variable name), and hence no concatenation occurs, and it's just a 
syntax error after that.

Read about compilation stages in section 2.1 of the Standard.  Macro 
substitution is also described in section 16.3.

V
-- 
I do not respond to top-posted replies, please don't ask

[toc] | [prev] | [next] | [standalone]


#8058

FromPaul Brettschneider <paul.brettschneider@yahoo.fr>
Date2011-07-21 23:27 +0200
Message-ID<cf7ac$4e2899cd$506c0d9c$19404@news.chello.at>
In reply to#8053
Hi,

Victor Bazarov wrote:

> On 7/21/2011 2:36 PM, Paul Brettschneider wrote:
>> Balog Pal wrote:
>>
>>> 2. #define is just for last resort -- use C++ native stuff wherever
>>> possible.
>>
>> Somewhat off-topic: What is the C++-way of implementing string literal
>> macros for use with concetenation?
> 
> It's a simple text replacement.  There are no "string literal macros".
> 
>>
>> What I mean is this:
>>
>> #define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
>> static const char control_sequence[] = "\xde\xad\xbe\xef";
>> static const char *f1()
>> {
>>          return "Test " CONTROL_SEQUENCE " string"; // Compiles but ugly
> 
> This is converted by the preprocessor into
> 
> return "Test " "\xde\xad\xbe\xef" " string";
> 
> (whitespace condenced, comments replaced with whitespace, macros are
> replaced with their "values" - straight text substitution), and then the
> adjacent string literals are concatenated (phase 6), so you get
> 
> return "Test \xde\xad\xbe\xef string";
> 
> just before the compiler gets that list of *tokens*.
> 
>> }
>> static const char *f2()
>> {
>>          return "Test " control_sequence " string"; // Error
>> }
> 
> There is no textual replacement here.  It's a different list of tokens
> the compiler gets:
> 
> return "Test " control_sequence " string";
> 
> in which no string literal appears in place of 'control_sequence' (which
> is a variable name), and hence no concatenation occurs, and it's just a
> syntax error after that.
> 
> Read about compilation stages in section 2.1 of the Standard.  Macro
> substitution is also described in section 16.3.

sorry for being unclear - I was well aware of all that. My question was if 
there is a C++ replacement for this C-ism, which I happen to use quite 
frequently. After all we're always told that macros (not type safe, side 
effects) should be replaced by inline/template functions or const-
expressions. But I haven't figured out how to concatenate string literals 
with const-expressions.

Thanks.

[toc] | [prev] | [next] | [standalone]


#8059

FromIan Collins <ian-news@hotmail.com>
Date2011-07-22 09:35 +1200
Message-ID<98rkdhFroiU4@mid.individual.net>
In reply to#8048
On 07/22/11 06:36 AM, Paul Brettschneider wrote:
> Balog Pal wrote:
>
>> 2. #define is just for last resort -- use C++ native stuff wherever
>> possible.
>
> Somewhat off-topic: What is the C++-way of implementing string literal
> macros for use with concetenation?
>
> What I mean is this:
>
> #define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
> static const char control_sequence[] = "\xde\xad\xbe\xef";

static const std::string control_sequence = "\xde\xad\xbe\xef";

> static const char *f1()
> {
>          return "Test " CONTROL_SEQUENCE " string"; // Compiles but ugly
> }

> static const char *f2()
> {
>          return "Test " control_sequence " string"; // Error
> }

static std::string f2()
{
   return "Test " + control_sequence + " string"; // No error
}

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#8060

FromPaul Brettschneider <paul.brettschneider@yahoo.fr>
Date2011-07-21 23:57 +0200
Message-ID<218db$4e28a0ae$506c0d9c$19918@news.chello.at>
In reply to#8059
Ian Collins wrote:

> On 07/22/11 06:36 AM, Paul Brettschneider wrote:
>> Balog Pal wrote:
>>
>>> 2. #define is just for last resort -- use C++ native stuff wherever
>>> possible.
>>
>> Somewhat off-topic: What is the C++-way of implementing string literal
>> macros for use with concetenation?
>>
>> What I mean is this:
>>
>> #define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
>> static const char control_sequence[] = "\xde\xad\xbe\xef";
> 
> static const std::string control_sequence = "\xde\xad\xbe\xef";
> 
>> static const char *f1()
>> {
>>          return "Test " CONTROL_SEQUENCE " string"; // Compiles but ugly
>> }
> 
>> static const char *f2()
>> {
>>          return "Test " control_sequence " string"; // Error
>> }
> 
> static std::string f2()
> {
>    return "Test " + control_sequence + " string"; // No error
> }

Yes, you are right. And even that works:
#include <string>
#include <vector>
static const std::string control_sequence = "\xde\xad\xbe\xef";
const std::vector<std::string> messages = {
        "Test " + control_sequence + " string",
        "Test " + control_sequence + " string2",
        "Test " + control_sequence + " string3"
};

I compared the code produced by g++ to

#define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
const char *messages[] = {
        "Test " CONTROL_SEQUENCE " string",
        "Test " CONTROL_SEQUENCE " string2",
        "Test " CONTROL_SEQUENCE " string3"
};

and the difference isn't pretty. :) Of course this may or may not be 
relevant and smart compilers may produce much better code.

[toc] | [prev] | [next] | [standalone]


#8062

FromThomas Boell <tboell@domain.invalid>
Date2011-07-22 01:06 +0200
Message-ID<20110722010603.586306a4@arcadia>
In reply to#8059
On Fri, 22 Jul 2011 09:35:45 +1200
Ian Collins <ian-news@hotmail.com> wrote:

> On 07/22/11 06:36 AM, Paul Brettschneider wrote:
> > Balog Pal wrote:
> >
> >> 2. #define is just for last resort -- use C++ native stuff wherever
> >> possible.
> >
> > Somewhat off-topic: What is the C++-way of implementing string literal
> > macros for use with concetenation?
> >
> > What I mean is this:
> >
> > #define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
> > static const char control_sequence[] = "\xde\xad\xbe\xef";
> 
> static const std::string control_sequence = "\xde\xad\xbe\xef";
> 
> > static const char *f1()
> > {
> >          return "Test " CONTROL_SEQUENCE " string"; // Compiles but ugly
> > }
> 
> > static const char *f2()
> > {
> >          return "Test " control_sequence " string"; // Error
> > }
> 
> static std::string f2()
> {
>    return "Test " + control_sequence + " string"; // No error
> }

Which is, of course, something totally different than Paul's
original example...

What is the problem with concatenating string literals at compile time,
anyway?

[toc] | [prev] | [next] | [standalone]


#8063

FromIan Collins <ian-news@hotmail.com>
Date2011-07-22 11:14 +1200
Message-ID<98rq7iFroiU7@mid.individual.net>
In reply to#8062
On 07/22/11 11:06 AM, Thomas Boell wrote:
> On Fri, 22 Jul 2011 09:35:45 +1200
> Ian Collins<ian-news@hotmail.com>  wrote:
>
>> On 07/22/11 06:36 AM, Paul Brettschneider wrote:
>>> Balog Pal wrote:
>>>
>>>> 2. #define is just for last resort -- use C++ native stuff wherever
>>>> possible.
>>>
>>> Somewhat off-topic: What is the C++-way of implementing string literal
>>> macros for use with concetenation?
>>>
>>> What I mean is this:
>>>
>>> #define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
>>> static const char control_sequence[] = "\xde\xad\xbe\xef";
>>
>> static const std::string control_sequence = "\xde\xad\xbe\xef";
>>
>>> static const char *f1()
>>> {
>>>           return "Test " CONTROL_SEQUENCE " string"; // Compiles but ugly
>>> }
>>
>>> static const char *f2()
>>> {
>>>           return "Test " control_sequence " string"; // Error
>>> }
>>
>> static std::string f2()
>> {
>>     return "Test " + control_sequence + " string"; // No error
>> }
>
> Which is, of course, something totally different than Paul's
> original example...

He asked for a C++ alternative to string literal concatenation, which is 
what he got!

> What is the problem with concatenating string literals at compile time,
> anyway?

There isn't one.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#8078

FromPaul Brettschneider <paul.brettschneider@yahoo.fr>
Date2011-07-22 08:49 +0200
Message-ID<df02d$4e291d6e$506c0d9c$28226@news.chello.at>
In reply to#8062
Thomas Boell wrote:

> On Fri, 22 Jul 2011 09:35:45 +1200
> Ian Collins <ian-news@hotmail.com> wrote:
> 
>> On 07/22/11 06:36 AM, Paul Brettschneider wrote:
>> > Balog Pal wrote:
>> >
>> >> 2. #define is just for last resort -- use C++ native stuff wherever
>> >> possible.
>> >
>> > Somewhat off-topic: What is the C++-way of implementing string literal
>> > macros for use with concetenation?
>> >
>> > What I mean is this:
>> >
>> > #define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
>> > static const char control_sequence[] = "\xde\xad\xbe\xef";
>> 
>> static const std::string control_sequence = "\xde\xad\xbe\xef";
>> 
>> > static const char *f1()
>> > {
>> >          return "Test " CONTROL_SEQUENCE " string"; // Compiles but
>> >          ugly
>> > }
>> 
>> > static const char *f2()
>> > {
>> >          return "Test " control_sequence " string"; // Error
>> > }
>> 
>> static std::string f2()
>> {
>>    return "Test " + control_sequence + " string"; // No error
>> }
> 
> Which is, of course, something totally different than Paul's
> original example...

Hm, I would not say totally. But there clearly are differences which stem 
from the fact POD vs. non-POD. For example this works:

#define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
constexpr const char *f1()
{
        return "Test " CONTROL_SEQUENCE " string";
}

while this doesn't:

static const std::string control_sequence = "\xde\xad\xbe\xef";
constexpr std::string f2()
{
        return "Test " + control_sequence + " string",
}
// error: return type ‘std::string’ is not literal type

Interestingly, this *does* work:

static const std::string control_sequence = "\xde\xad\xbe\xef";
constexpr const char *f2()
{
        static std::string s = "Test " + control_sequence + " string";
        return s.c_str();
}

But the code is more ugly than the macro version.

> What is the problem with concatenating string literals at compile time,
> anyway?

Macros are evil. :) For example there is no scoping. I wish I could put 
those control sequences inside a class, an enum or at least a namespace.
And I think it's curious that in times of templates where whole algorithms 
are resolved at compile time, simple string literal concatenation is pushed 
in the opposite direction from compile to runtime. Personally, I probably 
will stay with the macro version, since it is not very intrusive and doesn't 
have the usual problems of multiple evaluation of arguments, etc.

Thank you for all the comments so far.

[toc] | [prev] | [next] | [standalone]


#8088

FromJoe Greer <jgreer@doubletake.com>
Date2011-07-22 13:23 +0000
Message-ID<Xns9F2A5F828E7E3jgreerdoubletakecom@88.198.244.100>
In reply to#8078
Paul Brettschneider <paul.brettschneider@yahoo.fr> wrote in
news:df02d$4e291d6e$506c0d9c$28226@news.chello.at: 

> 
> Hm, I would not say totally. But there clearly are differences which
> stem from the fact POD vs. non-POD. For example this works:
> 
> #define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
> constexpr const char *f1()
> {
>         return "Test " CONTROL_SEQUENCE " string";
> }
> 
> while this doesn't:
> 
> static const std::string control_sequence = "\xde\xad\xbe\xef";
> constexpr std::string f2()
> {
>         return "Test " + control_sequence + " string",
> }
> // error: return type ‘std::string’ is not literal type
> 
> Interestingly, this *does* work:
> 
> static const std::string control_sequence = "\xde\xad\xbe\xef";
> constexpr const char *f2()
> {
>         static std::string s = "Test " + control_sequence + " string";
>         return s.c_str();
> }
> 
> But the code is more ugly than the macro version.
> 
>> What is the problem with concatenating string literals at compile
>> time, anyway?
> 
> Macros are evil. :) For example there is no scoping. I wish I could
> put those control sequences inside a class, an enum or at least a
> namespace. And I think it's curious that in times of templates where
> whole algorithms are resolved at compile time, simple string literal
> concatenation is pushed in the opposite direction from compile to
> runtime. Personally, I probably will stay with the macro version,
> since it is not very intrusive and doesn't have the usual problems of
> multiple evaluation of arguments, etc. 
> 
> Thank you for all the comments so far.

The problem is that 

static const std::string control_sequence = "\xde\xad\xbe\xef";

is not a literal.  It is a constant object of type string and as such is limited by the interface 
that a normal object is allowed to present.  The compiler doesn't usually know anything special about 
strings.  By design, they are a library concern and not a compiler concern.  Of course, since 
std::string is standard, the compiler could know something and generate the code you want without any 
special tricks, but that would be an optimization and you couldn't count on every compiler doing 
that.  On the otherhand, literals like "blah" are known by every compiler and provision is made in 
the language such that "blah" "blech" can be combined by the compiler to "blahblech" at compile time.  
As soon as you throw an object instance into mix (even a constant one), the compiler can't do much 
with it because object instances provide runtime behavior and not compile time behavior.  I haven't 
really had an opportunity/need to use constexpr yet, but I suspect that the first doesn't work 
because you are asking it to construct a new object each time.  The second works because it can 
create the string statically once and then just return its address.  Have you considered just:

static const std::string control_sequence = "\xde\xad\xbe\xef";
static const std::string f2 = "Test " + control_sequence + " string";

That should work too.  Of course, it's not trully generating a literal like the macros would, but 
this would be evaluted once and reused everywhere.  I doubt the runtime costs would be be measurable.

joe

[toc] | [prev] | [next] | [standalone]


#8107

FromJames Kanze <james.kanze@gmail.com>
Date2011-07-22 12:58 -0700
Message-ID<3569e818-0b5d-4ebe-8df6-52274c565f2c@cq10g2000vbb.googlegroups.com>
In reply to#8078
On Jul 22, 7:49 am, Paul Brettschneider <paul.brettschnei...@yahoo.fr>
wrote:
> Thomas Boell wrote:
> > On Fri, 22 Jul 2011 09:35:45 +1200
> >> > What I mean is this:

> >> > #define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
> >> > static const char control_sequence[] = "\xde\xad\xbe\xef";

> >> static const std::string control_sequence = "\xde\xad\xbe\xef";

> >> > static const char *f1()
> >> > {
> >> >          return "Test " CONTROL_SEQUENCE " string"; // Compiles but
> >> >          ugly
> >> > }

> >> > static const char *f2()
> >> > {
> >> >          return "Test " control_sequence " string"; // Error
> >> > }

> >> static std::string f2()
> >> {
> >>    return "Test " + control_sequence + " string"; // No error
> >> }

> > Which is, of course, something totally different than Paul's
> > original example...

> Hm, I would not say totally. But there clearly are differences which stem
> from the fact POD vs. non-POD. For example this works:

> #define CONTROL_SEQUENCE "\xde\xad\xbe\xef"
> constexpr const char *f1()
> {
>         return "Test " CONTROL_SEQUENCE " string";
> }

> while this doesn't:

> static const std::string control_sequence = "\xde\xad\xbe\xef";
> constexpr std::string f2()
> {
>         return "Test " + control_sequence + " string",}

> // error: return type ‘std::string’ is not literal type

> Interestingly, this *does* work:

> static const std::string control_sequence = "\xde\xad\xbe\xef";
> constexpr const char *f2()
> {
>         static std::string s = "Test " + control_sequence + " string";
>         return s.c_str();
> }

> But the code is more ugly than the macro version.

It also suffers from order of initialization problems.  There
are still cases where a macro is the best solution.

> > What is the problem with concatenating string literals at
> > compile time, anyway?

> Macros are evil. :)

Macros have a certain number of known defects.  That doesn't
mean that they're never the best solution.  (Try defining
something in the command line of the compiler, for example.
Like a version number.)

--
James Kanze

[toc] | [prev] | [next] | [standalone]


#8105

FromJames Kanze <james.kanze@gmail.com>
Date2011-07-22 12:51 -0700
Message-ID<965b5c6f-8e8b-4649-ba97-3f6ced495347@x12g2000yql.googlegroups.com>
In reply to#8043
On Jul 21, 4:34 pm, "Balog Pal" <p...@lib.hu> wrote:
> "Christopher" <cp...@austin.rr.com>

> >I don't use #defines myself, or very rarely. We are in the
> >middle of a style war and a coding style is being written up.

> Reimplementing the wheel? Isn't the Sutter/Alexandrescu 101
> book good enough for your place?

Not really.  Despite its name, it doesn't address most of the
issues a coding guidelines should address.

> > Which brings the
> > topic of #define in preexisting code.

> > Obviously, #define directives the header needs will have to go in the
> > header. But what of all of the #defines that are used like constants?

> > example
> > #define MYSILLYSTRING "I'm a String"

> > When these are only used in a class' .cpp?

> > Should these go in the .h or the .cpp file? Reasoning?

> 1. header files are for shared stuff. what must be shared goes there. What
> must not goes elsewhere.

And what isn't required to be shared shouldn't be.

> 2. #define is just for last resort -- use C++ native stuff wherever
> possible.

Use #define where ever it's most appropriate.  In general, I try
to avoid it in headers (except for the include guards), because
of the lack of scope, but I have no qualms about using it for
boilerplate code in the source files.  (And of course, there are
cases where it is necessary: if you want to automatically insert
__LINE__ or __FILE__ somewhere, for example.)

> 3. where you are left with #define name it so it can not be confused with
> anything else, and especially can not replace a part of existing code.
> (like the evil GetMessage macro in windowsx.h)

Or String in X.h:-).  In a source file, rather than a header,
this is a bit less critical, but I still tend to favor it.

Also, once you no longer need the #define, use #undef to get rid
of it.  (But I see you've mentionned that in point 5.  It's
often overlooked.)

> 4. If you have the strudy naming convintion from #3 it is no longer so
> interesting where the macro was defined. So just use #1 for decision
> 5. use #undef for macros of short intended scope

--
James Kanze

[toc] | [prev] | [next] | [standalone]


#8081

Fromgwowen <gwowen@gmail.com>
Date2011-07-22 00:29 -0700
Message-ID<5511c63f-c86b-4633-9307-8fa63f3da98a@a31g2000vbt.googlegroups.com>
In reply to#8041
On Jul 21, 4:11 pm, Christopher <cp...@austin.rr.com> wrote:
> I don't use #defines myself, or very rarely. We are in the middle of a
> style war and a coding style is being written up. Which brings the
> topic of #define in preexisting code.

If you can't explain the reasons you're doing something -- and can't
come up with any reasons yourself -- why do you feel so strongly about
it that you're getting involved in a war over it?

Cargo cult programming is scary.

[toc] | [prev] | [next] | [standalone]


#8120

FromChristopher <cpisz@austin.rr.com>
Date2011-07-22 15:56 -0700
Message-ID<359ba7f1-15d5-4684-893a-56a5427ad09e@v7g2000vbk.googlegroups.com>
In reply to#8081
On Jul 22, 2:29 am, gwowen <gwo...@gmail.com> wrote:
> On Jul 21, 4:11 pm, Christopher <cp...@austin.rr.com> wrote:
>
> > I don't use #defines myself, or very rarely. We are in the middle of a
> > style war and a coding style is being written up. Which brings the
> > topic of #define in preexisting code.
>
> If you can't explain the reasons you're doing something -- and can't
> come up with any reasons yourself -- why do you feel so strongly about
> it that you're getting involved in a war over it?
>
> Cargo cult programming is scary.

I never said I felt strongly about it. "It" being the #define
placement. I feel very strongly about some of the other issues
involved in a coding standard, but they aren't mentioned in this post.
I am simply curious as to what guidelines there might already be,
since it is a topic that is part of a "coding standard." and a
standard is getting put into place.

I am involved, because whatever decisions get made as a whole will
effect my day to day work. I'd be silly not to be involved.

[toc] | [prev] | [next] | [standalone]


#8089

FromJuha Nieminen <nospam@thanks.invalid>
Date2011-07-22 14:33 +0000
Message-ID<4e298a4b$0$2822$7b1e8fa0@news.nbl.fi>
In reply to#8041
Christopher <cpisz@austin.rr.com> wrote:
> Should these go in the .h or the .cpp file? Reasoning?

  Why should it go in the header file?

  A header file should only contain the bare minimum public interface of
the module it's representing. If the string constant in question is an
internal implementation detail of the module, putting it in the header
is horribly and absolutely *wrong*. It's the same as putting a private
variable in the public global namespace for absolutely no reason.

[toc] | [prev] | [next] | [standalone]


#8246

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2011-07-26 11:26 +0000
Message-ID<slrnj2t93l.gtj.grahn+nntp@frailea.sa.invalid>
In reply to#8089
On Fri, 2011-07-22, Juha Nieminen wrote:
> Christopher <cpisz@austin.rr.com> wrote:
>> Should these go in the .h or the .cpp file? Reasoning?
>
>   Why should it go in the header file?
>
>   A header file should only contain the bare minimum public interface of
> the module it's representing. If the string constant in question is an
> internal implementation detail of the module, putting it in the header
> is horribly and absolutely *wrong*.

And it's worth pointing out that it's wrong.

I see fairly frequently people use the header file as if foo.h was
some kind of "table of contents" for foo.cc. Or as if it was "input
parameters" to foo.cc, so that anything you may want to tweak (magic
constants, buffer sizes, fixed file names) are in the header file.

People who do that have good intentions, but it's much more important
to minimize the "information load" on the global level.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#8266

FromJuha Nieminen <nospam@thanks.invalid>
Date2011-07-26 16:14 +0000
Message-ID<4e2ee7d5$0$2824$7b1e8fa0@news.nbl.fi>
In reply to#8246
Jorgen Grahn <grahn+nntp@snipabacken.se> wrote:
> I see fairly frequently people use the header file as if foo.h was
> some kind of "table of contents" for foo.cc. Or as if it was "input
> parameters" to foo.cc, so that anything you may want to tweak (magic
> constants, buffer sizes, fixed file names) are in the header file.

  To be fair, it's an interesting question that if you wanted a library
to be "customizable" at compile time, what would be the best design for
this. (These may be things that *must* be decided at compile time because
they can't be decided at runtime. For example dependence on some non-standard
library.)

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web