473,714 Members | 2,158 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

What do these warnings mean?

I'm trying to initialize an array of error messages, so that I can
print out an error message by using the 'nth string in an array, e.g.

printf("%s\n", messages[n]);

I'm still hazy on arrays of pointers to strings, so you may want to
finish your drinks before examining my code. Here's a small sample
program.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *messages[4] = {"Hell", "o", " ", "world"};
printf("%s%s%s% s%s\n", messages[1], messages[2],
messages[0], messages[2], messages[3] );
return EXIT_SUCCESS;
}

Compiled under gcc in excruciatingly ansi mode (-ansi -pedantic, and a
few other esoteric options as well), it gives...

[20:21:02][/misc/home/user2/tbrg] ./test1
o Hell world

That's what I expected. But the compiler gives the following
warnings, related to the "char *messages[4]" declaration...

test1.c: In function `main':
test1.c:6: warning: initialization discards qualifiers from pointer target type
test1.c:6: warning: initialization discards qualifiers from pointer target type
test1.c:6: warning: initialization discards qualifiers from pointer target type
test1.c:6: warning: initialization discards qualifiers from pointer target type

Since gcc's warnings have spotted a few "legal" howlers of mine
already, I take them seriously. What am I doing wrong, and how can I
correct it ?

--
Walter Dnes; my email address is *ALMOST* like wz*******@waltd nes.org
Delete the "z" to get my real address. If that gets blocked, follow
the instructions at the end of the 550 message.
Nov 14 '05 #1
15 2624
[...]
That's what I expected. But the compiler gives the following
warnings, related to the "char *messages[4]" declaration...


i cant tell you for sure, but i suppose it is the absence of const what gcc
tries to tell you (but it still perfectly valid C, K&R at least)
try to declare it

const char * foo[] = {"1", "2", "3", "4"};

C compiler must accept
char * c = "12345";
but you are not allowed to change the values (not in C89, C99)
c[0] = 2;

that is why, the prefered and clenn way should be
const char * c ="12345";
c[0] = 2; // <--error

my 50 cent

--
Daniel
Nov 14 '05 #2
"Walter Dnes (delete the 'z' to get my real address)" wrote:

I'm trying to initialize an array of error messages, so that I can
print out an error message by using the 'nth string in an array, e.g.
.... snip ... {
char *messages[4] = {"Hell", "o", " ", "world"}; .... snip ...
That's what I expected. But the compiler gives the following
warnings, related to the "char *messages[4]" declaration...

test1.c: In function `main':
test1.c:6: warning: initialization discards qualifiers from pointer target type .... snip ...
Since gcc's warnings have spotted a few "legal" howlers of mine
already, I take them seriously. What am I doing wrong, and how
can I correct it ?


Define that array as "const char *messages[4] = ...." Those
messages are unmodifiable. Say so.

--
"The most amazing achievement of the computer software industry
is its continuing cancellation of the steady and staggering
gains made by the computer hardware industry..." - Petroski
Nov 14 '05 #3
In article <news:2i******* *****@uni-berlin.de>
Walter Dnes <se************ *************** **@waltdnes.org > wrote
(in part):
char *messages[4] = {"Hell", "o", " ", "world"};
Compiled under gcc in excruciatingly ansi mode (-ansi -pedantic, and a
few other esoteric options as well), it gives...
One of those "esoteric" options was, presumably, "-Wwrite-strings".

In C, a string literal[%] produces an "array N of char" object,
where N is one more than the number of characters inside the literal
-- the extra 1 is for the terminating '\0'. It is quite OK to use
the value of the object to initialize a "char *" variable:

char *p = "zorg";

The type of the anonymous "ought to have been", but for historical
reasons is not, "array N of const char". Notice the extra "const"
here. If it *had* been, the above would clearly be shorthand for:

/* str00007 is because (apparently) there were 6 other
string literals earlier. */
static const char str00007[] = { 'z', 'o', 'r', 'g', '\0' };
char *p = &str00007[0];

and *this* would require a diagnostic such as:
warning: initialization discards qualifiers from pointer target type


because &str00007[0] is "const char *", but p is just plain "char *"
-- the "const"-qualifier is missing.

Now, the peculiar thing about string literals in ANSI C is, they
really *are* read-only -- if you write on one, the effect is
undefined, and a "good" system such as a BSD or Linux will give
you a runtime trap. Yet, even though they are read-only, and the
"const" keyword *means* read-only, they do not have the "const"
attribute. This is for historical compatibility: before the 1989
C standard, there *was* no "const" keyword. Programmers just had
to be careful not to write on read-only objects. Hence, the world
is full of (perfectly good) C code that does not *use* "const".

GCC's "-Wwrite-strings" flag tells gcc that you, the programmer,
want the missing "const" stuck in. If you do this, you will get
warnings where none are required. It is quite OK to use a plain
"char *" to point at a string literal, and such code does exist,
so this warning could be annoying. Still, you have to be careful
not to write on it:

char *p = "zorg";

is fine; you just have to make sure you do not, later, try to do
something like:

p[0] = 'Z'; /* oops, was supposed to be uppercase */

If you make p have type "const char *", the compiler will be able
to catch this mistake at compile-time, and the code will compile
cleanly both with and without "-Wwrite-strings".

GCC's optional warning gives you a choice: "warn me about missing
`const's so I do not forget and try to write through the pointer",
or "do not warn me about this, because it is OK if I do not forget,
and the warning is annoying". You get to decide which of these
holds true for your own code.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #4
Walter Dnes (delete the 'z' to get my real address) wrote:
[..]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *messages[4] = {"Hell", "o", " ", "world"};
printf("%s%s%s% s%s\n", messages[1], messages[2],
messages[0], messages[2], messages[3] );
return EXIT_SUCCESS;
}

Compiled under gcc [...] the compiler gives the following
warnings, related to the "char *messages[4]" declaration...


So what does this do?

#include <stdio.h>
#include <string.h>
int main(void)
{
const char *messages[] = { "Hell", "o", " ", "world" };
printf("%s%s%s% s%s\n", messages[1], messages[2],
messages[0], messages[2], messages[3]);
return 0;
}

Nov 14 '05 #5
The unanimous consenus from the replies is that I'm missing "const" in
the declaration. I got rid of the warnings by changing it to...

const char *messages[] = {"Hell", "o", " ", "world"};

As someone correctly deduced, one of my "esoteric options" was
"-Wwrite-strings". Because I'm using it to set up error messages in the
app I'm currently doing, "const" is OK, and a nice sanity-check. For
future reference, in case I do have to initialize at runtime, the
following compiles+runs without warnings. Other than the fact that it's
a trivial example, any comments/suggestions ?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *messages[4];

char string_a[5];
char string_b[2];
char string_c[2];
char string_d[6];

strcpy(string_a , "Hell");
strcpy(string_b , "o");
strcpy(string_c , " ");
strcpy(string_d , "world");

messages[0] = string_a;
messages[1] = string_b;
messages[2] = string_c;
messages[3] = string_d;

printf("%s%s%s% s%s\n", messages[1], messages[2],
messages[0], messages[2], messages[3] );
return EXIT_SUCCESS;
}
--
Walter Dnes; my email address is *ALMOST* like wz*******@waltd nes.org
Delete the "z" to get my real address. If that gets blocked, follow
the instructions at the end of the 550 message.
Nov 14 '05 #6


Walter Dnes (delete the 'z' to get my real address) wrote:
The unanimous consenus from the replies is that I'm missing "const" in
the declaration. I got rid of the warnings by changing it to...

const char *messages[] = {"Hell", "o", " ", "world"};

As someone correctly deduced, one of my "esoteric options" was
"-Wwrite-strings". Because I'm using it to set up error messages in the
app I'm currently doing, "const" is OK, and a nice sanity-check. For
future reference, in case I do have to initialize at runtime, the
following compiles+runs without warnings. Other than the fact that it's
a trivial example, any comments/suggestions ?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *messages[4];

char string_a[5];
char string_b[2];
char string_c[2];
char string_d[6];

strcpy(string_a , "Hell");
strcpy(string_b , "o");
strcpy(string_c , " ");
strcpy(string_d , "world");

This will work, however, you can omit the strcpy statements
by initializing the char arrays on declaration.

char string_a[5] = "Hell";
etc
or
char string_a[] = "Hell";
char string_b[] = "o";
char string_c[] = " ";
char string_d[] = "world";
messages[0] = string_a;
messages[1] = string_b;
messages[2] = string_c;
messages[3] = string_d;

printf("%s%s%s% s%s\n", messages[1], messages[2],
messages[0], messages[2], messages[3] );
return EXIT_SUCCESS;
}


--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapi dsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #7
In <2i************ @uni-berlin.de> "Walter Dnes (delete the 'z' to get my real address)" <wz*******@walt dnes.org> writes:
I'm trying to initialize an array of error messages, so that I can
print out an error message by using the 'nth string in an array, e.g.

printf("%s\n ", messages[n]);

I'm still hazy on arrays of pointers to strings, so you may want to
finish your drinks before examining my code. Here's a small sample
program.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *messages[4] = {"Hell", "o", " ", "world"};
printf("%s%s%s% s%s\n", messages[1], messages[2],
messages[0], messages[2], messages[3] );
return EXIT_SUCCESS;
}

Compiled under gcc in excruciatingly ansi mode (-ansi -pedantic, and a
few other esoteric options as well), it gives...
NEVER ever use a compiler option whose meaning is not *perfectly* clear
to you... One of these esoteric options took the compiler out of
conforming ANSI mode.
[20:21:02][/misc/home/user2/tbrg] ./test1
o Hell world

That's what I expected. But the compiler gives the following
warnings, related to the "char *messages[4]" declaration...

test1.c: In function `main':
test1.c:6: warning: initialization discards qualifiers from pointer target type
test1.c:6: warning: initialization discards qualifiers from pointer target type
test1.c:6: warning: initialization discards qualifiers from pointer target type
test1.c:6: warning: initialization discards qualifiers from pointer target type

Since gcc's warnings have spotted a few "legal" howlers of mine
already, I take them seriously. What am I doing wrong, and how can I
correct it ?


Recompile the code using *only* options you do understand:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *messages[4] = {"Hell", "o", " ", "world"};
printf("%s%s%s% s%s\n", messages[1], messages[2],
messages[0], messages[2], messages[3] );
return EXIT_SUCCESS;
}
fangorn:~/tmp 86> gcc -ansi -pedantic -Wall test.c
fangorn:~/tmp 87>

See, there is nothing wrong with the code, the problem is using a gcc
inacantation you don't understand in the first place.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #8
In <40************ ***@yahoo.com> CBFalconer <cb********@yah oo.com> writes:
"Walter Dnes (delete the 'z' to get my real address)" wrote:

I'm trying to initialize an array of error messages, so that I can
print out an error message by using the 'nth string in an array, e.g.

... snip ...
{
char *messages[4] = {"Hell", "o", " ", "world"};

... snip ...

That's what I expected. But the compiler gives the following
warnings, related to the "char *messages[4]" declaration...

test1.c: In function `main':
test1.c:6: warning: initialization discards qualifiers from pointer target type

... snip ...

Since gcc's warnings have spotted a few "legal" howlers of mine
already, I take them seriously. What am I doing wrong, and how
can I correct it ?


Define that array as "const char *messages[4] = ...." Those
messages are unmodifiable. Say so.


Please engage your brain and answer the following simple question: in
standard C, what is the ultimate type his array initialisers are supposed
to have? Is this type compatible with the type of an array element?
If yes why would the const make any difference?

As it happens, the const is required by the fact that the OP is not using
his compiler in conforming mode and the initialisers have the *incorrect*
type. But this is something the OP needs to be *explicitly* explained,
otherwise your advice is downright confusing!

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #9
Dan Pop wrote:
CBFalconer <cb********@yah oo.com> writes:
.... snip ...

Define that array as "const char *messages[4] = ...." Those
messages are unmodifiable. Say so.

.... snip ...
As it happens, the const is required by the fact that the OP is
not using his compiler in conforming mode and the initialisers
have the *incorrect* type. But this is something the OP needs
to be *explicitly* explained, otherwise your advice is downright
confusing!


I happen to think the OP is using a suitable set of options for
new code, and that my reason for the revision is easily
understandable. The standard says the constants are not
necessarily modifiable. All the rest follows. He has found his
problem at compile time, rather than at some nebulous future run
time.

We can all be obscure at times, but this is not one of them. In
fact, I consider my advice to have been admirably succint. :-)

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!

Nov 14 '05 #10

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

Similar topics

3
1749
by: tony | last post by:
Hello!! I use VS 2003 and C# for all class library except MeltPracCommon.dll which is C++.NET The problem is that I get these warnings when building the exe file and use my class libraries. See below for a detail description. Preparing resources...
669
26006
by: Xah Lee | last post by:
in March, i posted a essay “What is Expressiveness in a Computer Language”, archived at: http://xahlee.org/perl-python/what_is_expresiveness.html I was informed then that there is a academic paper written on this subject. On the Expressive Power of Programming Languages, by Matthias Felleisen, 1990. http://www.ccs.neu.edu/home/cobbe/pl-seminar-jr/notes/2003-sep-26/expressive-slides.pdf
132
4617
by: Frederick Gotham | last post by:
If we look at a programming language such as C++: When an updated Standard comes out, everyone adopts it and abandons the previous one. It seems though that things aren't so clear-cut in the C community. It would seem that C99 is the most up-to-date Standard, but far more people seem to be working off the C89 Standard. Could someone please explain to me why this is so? --
98
4588
by: tjb | last post by:
I often see code like this: /// <summary> /// Removes a node. /// </summary> /// <param name="node">The node to remove.</param> public void RemoveNode(Node node) { <...> }
6
1907
by: pete142 | last post by:
When I compile this code: typedef unsigned char BYTE; BYTE * IpString(unsigned int ip) { static BYTE ipString; ipString = (BYTE) 0xff & (ip >24); ipString = (BYTE) 0xff & (ip >16);
92
6209
by: Heinrich Pumpernickel | last post by:
what does this warning mean ? #include <stdio.h> int main() { long l = 100; printf("l is %li\n", l * 10L);
45
9388
by: loudking | last post by:
Hello, all I don't quite understand what does ((time_t)-1) mean when I execute "man 2 time" RETURN VALUE On success, the value of time in seconds since the Epoch is retu rned. On error, ((time_t)-1) is returned, and errno is set
3
1705
by: neovantage | last post by:
Hey, Can some one guide me that from where these 2 css warnings come from as i am unable to find those id's in my css file named as here is the url which gives warnings on my contact page if some one guide me to figure out these 2 warnings located in my css then i will be really thanksful to him/her kind regards,
0
8713
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9318
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9187
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9032
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7957
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6638
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4467
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4730
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3160
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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

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