Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

warning: deprecated conversion from string constant to char*

94 views
Skip to first unread message

ag...@drrob1.com

unread,
Nov 9, 2014, 7:41:41 PM11/9/14
to
I am using Ubuntu 14.04 amd64 and am trying to learn using c++ for
Dummies (c) 2014 edition.

The book uses this syntax often, but gcc is saying
warning: deprecated conversion from string constant to char*
[-Wwrite-strings]

g++ -Wall -g -std=c++11 -o studentexample studentexample.cpp

This is studentexample.cpp
class Student {
public:
static int noOfStudents;
string name;

// warning flagged here
Student(const char * pName = "no name") : name(pName) {
nOfStudents++;
} // constructor

~Student() {
noOfStudents--;
} // destructor

const string REF getName() { return name; }
static FUNCTION int getNumber() { return noOfStudents; }
} // class Student

int Student::noOfStudents=0; // allocates space for the static data
//member and init's to 0.

int main() {

// warning flagged for both of these
Student s1("Chester");
Student * pS2 = new Student("Charlie");

cout << "No of s1.students " << s1.noOfStudents << endl;
cout << "Created " << s1.getName() << " and " << pS2->GetName()
<< endl;

cout << "Deleting " << pS2->getName() << endl;
delete pS2;
cout << " Number of students is now " << Student::getNumber()
<< endl;

return 0;
END;


What is the proper way to do what the book is doing that is not
deprecated?

Öö Tiib

unread,
Nov 9, 2014, 7:52:06 PM11/9/14
to
On Monday, 10 November 2014 02:41:41 UTC+2, ag...@drrob1.com wrote:
> I am using Ubuntu 14.04 amd64 and am trying to learn using
> c++ for Dummies (c) 2014 edition.
>
> The book uses this syntax often, but gcc is saying
> warning: deprecated conversion from string constant to char*
> [-Wwrite-strings]
>
> g++ -Wall -g -std=c++11 -o studentexample studentexample.cpp
>
> This is studentexample.cpp

Perhaps you did post some slice of real thing. If you want
to post code that gives warnings then post something that
does compile.

Ben Bacarisse

unread,
Nov 9, 2014, 7:55:01 PM11/9/14
to
ag...@drrob1.com writes:

> I am using Ubuntu 14.04 amd64 and am trying to learn using c++ for
> Dummies (c) 2014 edition.
>
> The book uses this syntax often, but gcc is saying
> warning: deprecated conversion from string constant to char*
> [-Wwrite-strings]
>
> g++ -Wall -g -std=c++11 -o studentexample studentexample.cpp
>
> This is studentexample.cpp

Really? The program you post and the errors you report are
inconsistent. The code below has a number of simple errors in it
(incorrect names, a missing semicolon, that sort of thing) but it does
not contain a conversion from string to char *.
You do what you've done -- the error does not exist in this code. (In
case you don't know what you've done, it's using const char * rather
than char *. It would generally be better to use std::string from the
outset, but that's another story.)

--
Ben.

ag...@drrob1.com

unread,
Nov 10, 2014, 8:04:49 AM11/10/14
to
On Mon, 10 Nov 2014 00:54:36 +0000, Ben Bacarisse
<ben.u...@bsb.me.uk> wrote:

>ag...@drrob1.com writes:
>
>> I am using Ubuntu 14.04 amd64 and am trying to learn using c++ for
>> Dummies (c) 2014 edition.
>>
>> The book uses this syntax often, but gcc is saying
>> warning: deprecated conversion from string constant to char*
>> [-Wwrite-strings]
>>
>> g++ -Wall -g -std=c++11 -o studentexample studentexample.cpp
>>
>> This is studentexample.cpp
>
>>
>>
>> What is the proper way to do what the book is doing that is not
>> deprecated?
>
>You do what you've done -- the error does not exist in this code. (In
>case you don't know what you've done, it's using const char * rather
>than char *. It would generally be better to use std::string from the
>outset, but that's another story.)

This is the code I actually use, with my macros and all. I tried to
remove these macros before posting, but it seems that I did not do
that correctly.

This code compiles on my computer.

#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <ctime>
#include <string> // string class of c++

#define EQ ==
#define NE !=
#define BEGIN {
#define END }
#define ENDIF }
#define ENDFOR }
#define ENDCASE }
#define ENDLOOP }
#define ENDWHILE }
#define ENDDOO } while // intended for the do { } while (expr);
looping construct
#define ENDFUNC }
#define ENDPROC }
#define MOD %
#define AND &&
#define OR ||
#define NOT !
#define THEN {
#define ELSE }else{
#define ELSIF }else if
#define IS {
#define DOO do { // intended for the do {} while (expr);
looping construct
#define DO {
#define LOOP {
#define ADROF &
#define ADR &
#define DEREF *
#define POINTERTO *
#define POINTER *
#define VAR &
#define REF &
#define PROCEDURE void
#define FUNCTION
#define BITAND &
#define BITOR |
#define BITNOT ~
#define BITXOR ^
#define argcargv int argc, char * argv[]
#define ADDRESS void* // typedef line is an error
#define COPY &
#define MOVE &&

typedef FILE* FileHandle;
typedef char* PointerToCharType;
typedef char* CharPointerType;

class Student IS
public:
static int noOfStudents;
string name;

Student(CharPointertype pName = "no name") : name(pName) IS
nOfStudents++;
END; // constructor

~Student() IS
noOfStudents--;
END; // destructor

const string REF getName() IS return name; END;
static FUNCTION int getNumber() IS return noOfStudents; END;
END; // class Student

int Student::noOfStudents=0; // allocates space for the static data
member and init's to 0.

FUNCTION int main(argcargv) IS

Student s1("Chester");
Student POINTER pS2 = new Student("Charlie");


cout << "No of s1.students " << s1.noOfStudents << endl;
cout << "No of Student::students " << Student::noOfStudents << end;
// equivalent way to access the static data element.

Richard Damon

unread,
Nov 10, 2014, 8:26:42 AM11/10/14
to
On 11/10/14, 8:04 AM, ag...@drrob1.com wrote:
> typedef char* CharPointerType;
>
> Student(CharPointertype pName = "no name") : name(pName) IS

(I am presuming the capitalization difference is a typo)

First suggest, burn any book that told you to use all those macros to
make your code more "readable", they just make things incomprehensible
for those who really know the language.

The above two lines show the problem.

CharPointerType is a pointer to NON-CONST char, while string literals
are defined as arrays of const char. (In C, the type was array of
non-writable but not-const char for historical reasons).

Since the Student constructor doesn't modify the character string passed
to it, it should declare that it takes a pointer to const char, not a
pointer to char, and things will be fine. (Your original posting of code
did that).

The reason this was just a warning and not a full error is that like 25
years ago, before C had const (and C++ was just being born), since the
language didn't have const, string literals would be assigned to char*
pointers (and on some systems WERE writeable). When const was added to
the language, it was thought to make C string literals to be const, but
that would have broken too much code since the pointers they wee being
assigned to weren't const (but many tools were set to be able to give
warnings for this, and over time this has become more of the default, as
hopefully most of that ancient code has been fixed). C++ on the other
hand, since it didn't have that large code base, defined string literals
to be const, but many tools would have an option to make this just a
warning (or even ignored) to help with porting these older programs to C++.

Ben Bacarisse

unread,
Nov 10, 2014, 8:57:30 AM11/10/14
to
ag...@drrob1.com writes:

> On Mon, 10 Nov 2014 00:54:36 +0000, Ben Bacarisse
> <ben.u...@bsb.me.uk> wrote:
>
>>ag...@drrob1.com writes:
>>
>>> I am using Ubuntu 14.04 amd64 and am trying to learn using c++ for
>>> Dummies (c) 2014 edition.
>>>
>>> The book uses this syntax often, but gcc is saying
>>> warning: deprecated conversion from string constant to char*
>>> [-Wwrite-strings]
>>>
>>> g++ -Wall -g -std=c++11 -o studentexample studentexample.cpp
>>>
>>> This is studentexample.cpp
>>
>>>
>>>
>>> What is the proper way to do what the book is doing that is not
>>> deprecated?
>>
>>You do what you've done -- the error does not exist in this code. (In
>>case you don't know what you've done, it's using const char * rather
>>than char *. It would generally be better to use std::string from the
>>outset, but that's another story.)
>
> This is the code I actually use, with my macros and all. I tried to
> remove these macros before posting, but it seems that I did not do
> that correctly.

No, and in doing the conversion you fixed the very problem you were
asking about! A simple compile run would have shown you that the
problem had gone away (once you'd fixed the other errors you'd
introduced). Anyway, you now know how to fix the problem, yes?

<snip>
> #define EQ ==
> #define NE !=
> #define BEGIN {
> #define END }
> #define ENDIF }
> #define ENDFOR }
> #define ENDCASE }
> #define ENDLOOP }
> #define ENDWHILE }

...and so on. Macros like thee are a very bad idea.

<snip>
> typedef char* PointerToCharType;
> typedef char* CharPointerType;

When you translated your code, you changed these types, thus fixing the
issue you were posting about.

<snip>
--
Ben.

Mr Flibble

unread,
Nov 10, 2014, 1:04:52 PM11/10/14
to
Dafuq? :/

/Flibble

Geoff

unread,
Nov 10, 2014, 4:39:09 PM11/10/14
to
This goes back more than 10 years to something called "Easy C" that
played havoc with the language. When I first saw something like this
it was related to the obfuscated C contests. It was horrible to
contemplate someone learning C this way. I haven't looked at the book
the OP cites but I hope that book doesn't contain this abomination.

Keith Thompson

unread,
Nov 10, 2014, 4:54:31 PM11/10/14
to
Geoff <ge...@invalid.invalid> writes:
[...]
>>On 10/11/2014 13:04, ag...@drrob1.com wrote:
>>> This is the code I actually use, with my macros and all. I tried to
>>> remove these macros before posting, but it seems that I did not do
>>> that correctly.
>>>
>>> This code compiles on my computer.
>>>
>>> #include <cstring>
>>> #include <cstdio>
>>> #include <iostream>
>>> using namespace std;
>>> #include <cstdlib>
>>> #include <cctype>
>>> #include <cmath>
>>> #include <ctime>
>>> #include <string> // string class of c++
>>>
>>> #define EQ ==
>>> #define NE !=
>>> #define BEGIN {
>>> #define END }
>>> #define ENDIF }
>>> #define ENDFOR }
>>> #define ENDCASE }
>>> #define ENDLOOP }
>>> #define ENDWHILE }
>>> #define ENDDOO } while // intended for the do { } while (expr);
[snip]
>
> This goes back more than 10 years to something called "Easy C" that
> played havoc with the language. When I first saw something like this
> it was related to the obfuscated C contests. It was horrible to
> contemplate someone learning C this way. I haven't looked at the book
> the OP cites but I hope that book doesn't contain this abomination.

Similar macros go back much further than that. The original Bourne
shell was written in C using macros intended to make it look like
Algol 68.

http://stackoverflow.com/a/1067349/827263
http://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

ag...@drrob1.com

unread,
Nov 10, 2014, 5:12:47 PM11/10/14
to
On Mon, 10 Nov 2014 08:04:33 -0500, ag...@drrob1.com wrote:

>On Mon, 10 Nov 2014 00:54:36 +0000, Ben Bacarisse
><ben.u...@bsb.me.uk> wrote:
>
>>ag...@drrob1.com writes:
>>
>>> I am using Ubuntu 14.04 amd64 and am trying to learn using c++ for
>>> Dummies (c) 2014 edition.
>>>
>>You do what you've done -- the error does not exist in this code. (In
>>case you don't know what you've done, it's using const char * rather
>>than char *. It would generally be better to use std::string from the
>>outset, but that's another story.)
>
>This is the code I actually use, with my macros and all. I tried to
>remove these macros before posting, but it seems that I did not do
>that correctly.
>
Thanks to all who replied. I now understand that I needed
const char *. For some reason, const CharPointerType did not do what
I hoped.

I have noticed that my macros offend experienced C-ish programmers. I
am not an experienced C-ish programmer, but come to this after many
years of working with other languages. What seems natural to my eye
is insulting to many.

This is why I first posted code without my macros. But I missed a few
of my macro references and that made some mad and not interested in
helping. So it goes.

--rob

Ian Collins

unread,
Nov 10, 2014, 5:20:13 PM11/10/14
to
ag...@drrob1.com wrote:
> On Mon, 10 Nov 2014 08:04:33 -0500, ag...@drrob1.com wrote:

<snip>

>> typedef FILE* FileHandle;
>> typedef char* PointerToCharType;
>> typedef char* CharPointerType;
>>
>
> Thanks to all who replied. I now understand that I needed
> const char *. For some reason, const CharPointerType did not do what
> I hoped.

This a a good, if not compelling, reason not to use such macros and
typedefs!

"const CharPointerType" qualifies CharPointerType as const, not what it
is pointing to.

> I have noticed that my macros offend experienced C-ish programmers. I
> am not an experienced C-ish programmer, but come to this after many
> years of working with other languages. What seems natural to my eye
> is insulting to many.

If you are going to learn C, drop the macros sooner rather than later
they don't help and can (and did) lead to confusion.

--
Ian Collins

Keith Thompson

unread,
Nov 10, 2014, 5:50:15 PM11/10/14
to
ag...@drrob1.com writes:
> On Mon, 10 Nov 2014 08:04:33 -0500, ag...@drrob1.com wrote:
[snip]
>>#define EQ ==
>>#define NE !=
>>#define BEGIN {
>>#define END }
[...]
> I have noticed that my macros offend experienced C-ish programmers. I
> am not an experienced C-ish programmer, but come to this after many
> years of working with other languages. What seems natural to my eye
> is insulting to many.

I don't think they're offensive or insulting. I just think they're
a really bad idea.

Consider this. One might argue that a language that uses "EQ",
"NE", "BEGIN", and "END" rather than C and C++'s "==", "!=", "{",
and "}" is better (more readable, more maintainable) than C or C++.
I wouldn't necessarily agree, but it's a perfectly valid opinion.

But that's not what those macros give you. Instead, they apply a
thin layer on top of standard C syntax.

To understand a program written using those macros, someone would
have to understand *both* standard C syntax *and* the macros (which
I'll guess are not documented anywhere other than in the header
file that defines them).

Ben Bacarisse

unread,
Nov 10, 2014, 6:27:11 PM11/10/14
to
ag...@drrob1.com writes:

> On Mon, 10 Nov 2014 08:04:33 -0500, ag...@drrob1.com wrote:
>
>>On Mon, 10 Nov 2014 00:54:36 +0000, Ben Bacarisse
>><ben.u...@bsb.me.uk> wrote:
>>
>>>ag...@drrob1.com writes:
>>>
>>>> I am using Ubuntu 14.04 amd64 and am trying to learn using c++ for
>>>> Dummies (c) 2014 edition.
>>>>
>>>You do what you've done -- the error does not exist in this code. (In
>>>case you don't know what you've done, it's using const char * rather
>>>than char *. It would generally be better to use std::string from the
>>>outset, but that's another story.)
>>
>>This is the code I actually use, with my macros and all. I tried to
>>remove these macros before posting, but it seems that I did not do
>>that correctly.

<snip>
>>#define EQ ==
>>#define NE !=
>>#define BEGIN {
>>#define END }
>>#define ENDIF }
>>#define ENDFOR }
>>#define ENDCASE }
<snip similar>
>>typedef FILE* FileHandle;
>>typedef char* PointerToCharType;
>>typedef char* CharPointerType;
>>
>
> Thanks to all who replied. I now understand that I needed
> const char *. For some reason, const CharPointerType did not do what
> I hoped.

The reason is that the const, here, applies to the type you defined as
CharPointerType -- it makes the pointer const. const char * is a
pointer to characters that are const.

> I have noticed that my macros offend experienced C-ish programmers. I
> am not an experienced C-ish programmer, but come to this after many
> years of working with other languages. What seems natural to my eye
> is insulting to many.

I'm not offended by them. I think they are a source of trouble.
Nothing checks them; new readers need to learn them; everyone does it
differently; the superficial similarity to other languages can be
misleading; ...

<snip>
--
Ben.

Chris Vine

unread,
Nov 10, 2014, 8:09:43 PM11/10/14
to
On Mon, 10 Nov 2014 17:12:33 -0500
I don't believe anyone could have considered themselves "insulted".
Probably people thought your approach confusing, and certainly
unnatural. Furthermore I doubt anyone became "mad". The problem was
that your posted code did not give rise to the problem that you claimed
it did, so there was no help that anyone could reasonably give. (There
were of course other (real) problems with your posted code.)

The best antidote to your desire to restructure the way that C and C++
syntax works is for you to learn a few other new languages as well. Try
learning a lisp/scheme and perhaps ruby or python to get a wider
perspective on programming approaches. Also, if you are going to post
code to the newsgroup, try to take the trouble to see if it compiles
first.

Chris

Paavo Helde

unread,
Nov 11, 2014, 1:14:45 AM11/11/14
to
Ian Collins <ian-...@hotmail.com> wrote in news:cccs0eFb6o3U2
@mid.individual.net:

> ag...@drrob1.com wrote:
>> On Mon, 10 Nov 2014 08:04:33 -0500, ag...@drrob1.com wrote:
>
> <snip>
>
>>> typedef FILE* FileHandle;
>>> typedef char* PointerToCharType;
>>> typedef char* CharPointerType;
>
> "const CharPointerType" qualifies CharPointerType as const, not what it
> is pointing to.
[...]
> If you are going to learn C, drop the macros sooner rather than later
> they don't help and can (and did) lead to confusion.

To be honest, the original problem here was caused by typedefs, not
macros. With a macro it would even have appeared to work better (probably
causing more confusion):

#define CharPointerType char*

const CharPointerType - OK, the macro gets replaced early and the
compiler sees 'const char*'. Not that I suggest to go that route, this
would be even worse than ENDFOR.

To OP: if you really want to use typedefs in this fashion, then you need
extra typedefs for 'const' variants. For example, Microsoft has something
along the lines of

typedef char *LPTSTR;
typedef const char *LPCTSTR;

One typically uses some kind of naming conventions for const variants,
like 'const_iterator' in STL. The 'C' in the Microsoft typedefs indicates
that string data is 'const', for example. Not that I would suggest to
adopt the Microsoft abominations either.

In C++ we actually have proper string types, so there is not much reason
to use 'const char*' at all in function interfaces. So the correct way to
write such interfaces is something like:

class Student {
public:
Student(const std::string& name = "no name") : name_(name) // ...

private:
std::string name_;
};


Cheers
Paavo

Jorgen Grahn

unread,
Nov 12, 2014, 10:21:05 AM11/12/14
to
On Tue, 2014-11-11, Chris Vine wrote:

...
> The best antidote to your desire to restructure the way that C and C++
> syntax works is for you to learn a few other new languages as well. Try
> learning a lisp/scheme and perhaps ruby or python to get a wider
> perspective on programming approaches.

That's really constructive advice -- I wish I had come up with it.
Yes, it's the way to go. (I'd choose Haskell over LISP, though.)

/Jorgen

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