LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-05-2013, 09:34 AM   #1
nkoplm
Member
 
Registered: May 2005
Distribution: Fedora
Posts: 92

Rep: Reputation: 15
Help with a simple c++ constexpr problem


Sorry for the code formatting, this was written on an iPad, but I am having trouble getting the c++11 constexpr to work.

I am simply trying to get "pass" and "fail" to be synonyms for bool true and false. It will increase the readability of my code.

I am still unfamiliar with c++11 and learning how it works. All examples I find online are usually more complicated examples and don't help me with this simple problem.

Code:
#include <iostream>
 
class cc {
public:
constexpr bool pass =true;
void print(){
std::cout << " [ "  << pass << " ] ";
}};
 
int main (){
 
  cc *dd = new cc();
  dd->print();
  return 0;
}
Code:
prog.cpp:5:22: error: non-static data member ‘pass’ declared ‘constexpr’
 constexpr bool pass =true;
                      ^
Any help getting this to work is appreciated. Thanks.

Last edited by nkoplm; 08-05-2013 at 09:35 AM.
 
Old 08-05-2013, 10:21 AM   #2
thirdm
Member
 
Registered: May 2013
Location: Massachusetts
Distribution: Slackware, NetBSD, Debian, 9front
Posts: 323

Rep: Reputation: Disabled
Either don't make it a member variable or make it a static member variable. That seems to me what the error message is telling you.

I haven't gotten to the chapter on constexpr yet, but looking here http://www.stroustrup.com/C++11FAQ.html#constexpr I note in the 3rd example that for Point to be usable at compile time he only needs to declare the ctor with constexpr, not the member variables. I guess simple static allocation of variables already can be done at compile time. I'm thinking you want constexpr to give you an alias to type literals but this link suggests its real intent is to make sure you get an error if the expression following can't be evaluated entirely at compile time. I'd think a simple const would be enough in your case (const + static if you insist on scoping this within your class?).

I don't find this code more readable, btw, especially considering your pass variable will be printed as 1, I think. At least, this is what I get in an ISO98 compiler. It promotes bool to int in your output statement.

Maybe what you really want is your own type (enum or enum class?) with the two values and an operator<<(ostream&) overload that prints pass for pass and fail for fail.
 
Old 08-05-2013, 10:26 AM   #3
thirdm
Member
 
Registered: May 2013
Location: Massachusetts
Distribution: Slackware, NetBSD, Debian, 9front
Posts: 323

Rep: Reputation: Disabled
Also, why do you use new here? It's irrelevant, but it's a pet peave of mine, people throwing stuff on the heap when it's unnecessary. And here you never bother to delete it. I realize it's just a toy example, but ugly to see.
 
Old 08-07-2013, 10:07 AM   #4
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
Quote:
Originally Posted by thirdm View Post
Also, why do you use new here? It's irrelevant, but it's a pet peave of mine, people throwing stuff on the heap when it's unnecessary. And here you never bother to delete it. I realize it's just a toy example, but ugly to see.
That seems to be the approach taken in Java where every Object variable (including arrays) is a pointer that needs to be assigned a valid heap address before it can be used.

I suppose someone who alternates between Java and C++ might like to take the same approach for both programs for consistency's sake. One could also develop a peeve about throwing variables used only by main() on the stack (shouldn't they be static?).

From the experiments I have done with C++ it seems to be a case of 6 of one and half a dozen of the other. However, I have found that when memory or Segmentation faults occur, it often points to a heap problem.
 
Old 08-07-2013, 10:31 AM   #5
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
Perhaps you should declare it as static as well. constexpr probably as compared to const truly allocates a space for itself unless not really used or needed, so declaring it as a member that has an initial value could just mean that it has to be allocated and defined for every object instance that doesn't make itself really constant on a specific allocation anymore. But this is just my opinion. I barely read the documentation from the link provided by thirdm so I could be wrong.
 
Old 08-07-2013, 10:38 AM   #6
thirdm
Member
 
Registered: May 2013
Location: Massachusetts
Distribution: Slackware, NetBSD, Debian, 9front
Posts: 323

Rep: Reputation: Disabled
Quote:
Originally Posted by psionl0 View Post
I suppose someone who alternates between Java and C++ might like to take the same approach for both programs for consistency's sake.
Consistency between code in different programming languages? Hmmm, I guess that's what makes the C part of the emacs source code such a joy to read. They're consistent between their Lisp code and their C code.

The person's going to the trouble of learning C++11. He or she should go to the trouble of moving to newer C++ styles, one of which is to favour value semantics in higher level code over pointer/reference semantics except when the latter is really needed, e.g. when data can't have simple local ownership or polymorphism is involved. I work on a C++ code base that's written more or less in a Java style (which is funny considering the architects wore Microsoft underwear and hated Java and anyone who suggested we should have used it instead -- of course now they have C# and love it -- so it goes -- if Bill Gates created Perl and IBM created Lisp I'd probably think them both shyte). To avoid rampant memory leaks the architects encouraged everyone to universally, with no thought, use a custom version of today's std::shared_ptr. Same code's supposed to be thread safe. The result: several (hundreds in some cases) of interlocked increments per function call. This is what comes of trying to be Java when you're not Java.

Here's an article that might be worth a read: https://akrzemi1.wordpress.com/2012/...lue-semantics/

I like how he expresses it. C++ gives you value semantics by default. See how it's shorter and cleaner without the pointer/new. Why fight the language on this?

Code:
int main()
{
  cc dd;
  dd.print();
  return 0;
}
 
Old 08-07-2013, 11:38 AM   #7
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
Quote:
Originally Posted by thirdm View Post
I like how he expresses it. C++ gives you value semantics by default. See how it's shorter and cleaner without the pointer/new. Why fight the language on this?

Code:
int main()
{
  static cc dd;
  dd.print();
  return 0;
}
ftfy.

BTW I agree with your comments. I was just making up a theory.
 
Old 08-07-2013, 11:56 AM   #8
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
@thirdm, FYI this is the test code I wrote a while ago when I was learning C++. It is actually translated from an example given in a Java book. It illustrates what you were saying:
Code:
#include <iostream>
using namespace std;

class Car {
   string colour;
   string body;
   string motion;

public:
   Car(string c = "Blue", string b = "Saloon", string m = "Putt putt") {
      colour = c;
      body = b;
      motion = m;
   };

   string getColour() {
      return colour;
   };
   string getBody() {
      return body;
   };
   string accelerate() {
      return motion;
   };
};

int main(void) {
      static Car Porsche("Red", "Coupe", "Vroom vroom");
      cout << "Porsche:\n";
      cout << "Finish is " << Porsche.getColour() << "\n";
      cout << "Body-type is " <<  Porsche.getBody() << "\n";
      cout << Porsche.accelerate() << "\n";

      Car *Jalopy = new Car();
      cout << "\nJalopy:\n";
      cout << "Finish is " << Jalopy->getColour() << "\n";
      cout << "Body-type is " << Jalopy->getBody() << "\n";
      cout << Jalopy->accelerate() << "\n";

      return 0;
}
 
Old 08-07-2013, 12:49 PM   #9
thirdm
Member
 
Registered: May 2013
Location: Massachusetts
Distribution: Slackware, NetBSD, Debian, 9front
Posts: 323

Rep: Reputation: Disabled
Quote:
Originally Posted by psionl0 View Post
ftfy.

BTW I agree with your comments. I was just making up a theory.
I'm not getting the theory. Why use static in this case?

Generally speaking having classes in static storage is a PITA since order of destruction is undefined there. Another of my pet peaves (I'm a grumpy guy apparently) comes from this because I get people at work who won't believe me when I say the spew from Microsoft's handy little c runtime debug function that tells you everything you forgot to free isn't meaningful for our program. I tell them this because we have all these (loosely engineered, nothing at the Alexandrescu or Meyers level) singletons with static storage and program lifetime that may or may not be released (multiple dlls are also involved here, which may be requisite for this problem) by the time the leak catcher runs. But they all give me this look that says, "okay sure buddy, denial ain't just a river..."

Actually, come to think of it, does a static of that kind, as opposed to something defined in global scope have this problem when the function is main? Could the compiler be safe in assuming when main exits nothing will call it again and destroy dd?
 
Old 08-07-2013, 09:28 PM   #10
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
Quote:
Originally Posted by thirdm View Post
I'm not getting the theory. Why use static in this case?

Generally speaking having classes in static storage is a PITA since order of destruction is undefined there.
With the exception of variables who's scope is limited to a block, most local function variables exist as long as the function is running. In the case of main() this means for the life of the program. Since main() is seldom re-entrant, it seems to be a waste of stack space to make such variables auto.

When main() ends, it's pretty much show over (with the exception of maybe returning a number to the OS). The program is removed from the process list and all of its memory returned to the OS. There seems to be little point in running destructors on any objects local to main() at this point. (It would be like incrementing a local counter just before exiting a function).

Of course, if you have any exceptions to the above case then by all means, put the object on the stack or heap. The beauty of C/C++ is that you have all of these options.

Last edited by psionl0; 08-07-2013 at 09:32 PM.
 
Old 08-07-2013, 11:23 PM   #11
thirdm
Member
 
Registered: May 2013
Location: Massachusetts
Distribution: Slackware, NetBSD, Debian, 9front
Posts: 323

Rep: Reputation: Disabled
Stupid pet trick:
Code:
#include <iostream>

int main();

struct Dog
{
	~Dog()
	{
		main();
	}
} odie;

int
main()
{
	static Dog trixie;
	static int i = 1;
	std::cout << "Call to main: " << i << '\n';
	++i;
	return i;
}


$ ./a.out
Call to main: 1
Call to main: 2
Call to main: 3
$ echo $?
2


Last edited by thirdm; 08-07-2013 at 11:45 PM. Reason: worsen
 
Old 08-08-2013, 12:20 AM   #12
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
There's always an exception that proves the rule.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Simple Slackware vs simple Arch vs simple Frugalware punchy71 Linux - Distributions 2 08-28-2012 02:30 PM
Simple Problem Looking for Simple Solution mccartjd Linux - Newbie 1 12-30-2011 08:02 PM
simple problem rugu Slackware 8 08-31-2007 09:34 AM
Yet another problem, but this one is simple! Taigrr Linux - Newbie 7 02-02-2006 07:04 PM
a simple C problem! kapsikum Programming 10 04-14-2005 03:07 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:30 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration