Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #8041 > unrolled thread
| Started by | Christopher <cpisz@austin.rr.com> |
|---|---|
| First post | 2011-07-21 08:11 -0700 |
| Last post | 2011-07-26 16:14 +0000 |
| Articles | 20 — 11 participants |
Back to article view | Back to comp.lang.c++
#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
| From | Christopher <cpisz@austin.rr.com> |
|---|---|
| Date | 2011-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]
| From | Victor Bazarov <v.bazarov@comcast.invalid> |
|---|---|
| Date | 2011-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]
| From | "Balog Pal" <pasa@lib.hu> |
|---|---|
| Date | 2011-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]
| From | Christopher <cpisz@austin.rr.com> |
|---|---|
| Date | 2011-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]
| From | Paul Brettschneider <paul.brettschneider@yahoo.fr> |
|---|---|
| Date | 2011-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]
| From | Victor Bazarov <v.bazarov@comcast.invalid> |
|---|---|
| Date | 2011-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]
| From | Paul Brettschneider <paul.brettschneider@yahoo.fr> |
|---|---|
| Date | 2011-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Paul Brettschneider <paul.brettschneider@yahoo.fr> |
|---|---|
| Date | 2011-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]
| From | Thomas Boell <tboell@domain.invalid> |
|---|---|
| Date | 2011-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | Paul Brettschneider <paul.brettschneider@yahoo.fr> |
|---|---|
| Date | 2011-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]
| From | Joe Greer <jgreer@doubletake.com> |
|---|---|
| Date | 2011-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]
| From | James Kanze <james.kanze@gmail.com> |
|---|---|
| Date | 2011-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]
| From | James Kanze <james.kanze@gmail.com> |
|---|---|
| Date | 2011-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]
| From | gwowen <gwowen@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Christopher <cpisz@austin.rr.com> |
|---|---|
| Date | 2011-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2011-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]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2011-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2011-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