468,773 Members | 2,338 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,773 developers. It's quick & easy.

please help with mysterious error....

Hi,

In continuation of the thread I made "perhaps a stack problem? Long
calculations - strange error?", I think I now got a "stable" error,
meaning that the error always seem to come here now (tried: visual
studio 2005 + linux/macintosh gcc)...

That's a pretty good thing. I think the error still appears using both
gcc and visual studio 2005. Everything is standard C (ANSI C ?? I don't
know the difference) - but since so many functions depend on different
variables it's hard for me to isolate the error or to make a minimal
example ready for posting...

What can I say: I don't get any compile errors/warning... I tried
valgrind, but it wrote something I didn't agree with or I didn't
understood what it disliked...
Instructions:

1) Download + unzip (there are no binaries so no viruses/spam/whatever)
2a) Under linux/mac os: just type "make" (makefile included)
2b) Under windows: I guess you just create a new project and drag the
*.c and *.h files into it and compile/build.
3a) Either run the program and see the error or
3b) put a breakpoint in "result_output.c" line 748, then step a few
lines and watch what happens.

What is wrong?
for(i=0; i<total_linepieces; i++);
{
printf("i = %d\n", i); /* i should be 0 now, right? */
if( i != 0)
{
printf("\n\nTHE PROGRAM DOESN'T WORK\n\n");
quit_program(__FILE__, __LINE__);
}
else
{
printf("\n\nTHANKS!!! THE PROGRAM WORKS\n");
quit_program(__FILE__, __LINE__);
}
}

Some memory-garbage-thing, probably...
I'm really really fed up and tired of this bug, because I can't find it
and the compiler doesn't help me...

I've prepared 2 archives: .zip + .tar.gz.

(enter code + click blue button "START DOWNLOAD")
zip: http://www.uploading.com/?get=N3PT46TP

(click "DOWNLOAD", yellow bar bottom right).
tar.gz: http://www.savefile.com/files/2695995
It would also be nice to know how to avoid such a problem in the future,
when the compiler doesn't help...
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 1 '06 #1
33 2549
Martin Jørgensen said:
Hi,

In continuation of the thread I made "perhaps a stack problem? Long
calculations - strange error?", I think I now got a "stable" error,
meaning that the error always seem to come here now (tried: visual
studio 2005 + linux/macintosh gcc)...


I got 92 lines of complaint from gcc.

Here are the edited highlights:

main.h:46: warning: declaration of `dx' shadows global declaration
main.h:47: warning: declaration of `dy' shadows global declaration

(lots and lots of similar diagnostics)

..//main.c:32: warning: passing arg 1 of `get_nx_ny_nz' discards qualifiers
from pointer target type
..//main.c:49: warning: passing arg 1 of `quit_program' discards qualifiers
from pointer target type

(lots and lots of similar diagnostics)

When you get a clean compile at a reasonably fascist warning level, come on
back.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 1 '06 #2
On Thu, 01 Jun 2006 18:17:12 +0200, Martin Jørgensen wrote:
Hi,

In continuation of the thread I made "perhaps a stack problem? Long
calculations - strange error?", I think I now got a "stable" error,
meaning that the error always seem to come here now (tried: visual
studio 2005 + linux/macintosh gcc)...

That's a pretty good thing. I think the error still appears using both
gcc and visual studio 2005. Everything is standard C (ANSI C ?? I don't
know the difference) - but since so many functions depend on different
variables it's hard for me to isolate the error or to make a minimal
example ready for posting...

What can I say: I don't get any compile errors/warning... I tried
valgrind, but it wrote something I didn't agree with or I didn't
understood what it disliked... <snip> What is wrong?
for(i=0; i<total_linepieces; i++); I think you should remove the semicolon here, now this line just
increments i until it's equal to 'total_linepieces', and afterwars the
following code gets executed.
{
printf("i = %d\n", i); /* i should be 0 now, right? */ if( i != 0) {
printf("\n\nTHE PROGRAM DOESN'T WORK\n\n"); quit_program(__FILE__,
__LINE__);
}
else
{
printf("\n\nTHANKS!!! THE PROGRAM WORKS\n"); quit_program(__FILE__,
__LINE__);
}
}

Some memory-garbage-thing, probably...
I'm really really fed up and tired of this bug, because I can't find it
and the compiler doesn't help me... <snip>
It would also be nice to know how to avoid such a problem in the future,
when the compiler doesn't help...
Best regards
Martin Jørgensen


Hope this helps,
Bas Wassink
Jun 1 '06 #3
Bas Wassink wrote:
On Thu, 01 Jun 2006 18:17:12 +0200, Martin Jørgensen wrote:

Hi,

In continuation of the thread I made "perhaps a stack problem? Long
calculations - strange error?", I think I now got a "stable" error,
meaning that the error always seem to come here now (tried: visual
studio 2005 + linux/macintosh gcc)...

That's a pretty good thing. I think the error still appears using both
gcc and visual studio 2005. Everything is standard C (ANSI C ?? I don't
know the difference) - but since so many functions depend on different
variables it's hard for me to isolate the error or to make a minimal
example ready for posting...

What can I say: I don't get any compile errors/warning... I tried
valgrind, but it wrote something I didn't agree with or I didn't
understood what it disliked...


<snip>
What is wrong?
for(i=0; i<total_linepieces; i++);


I think you should remove the semicolon here, now this line just
increments i until it's equal to 'total_linepieces', and afterwars the
following code gets executed.


OMFG! That code was driving me "#€%()#€%€(%##€(#€%( crazy and then I
just overlooked that? :-)

I think I've looked many other places, but that... Oh, well. Nice to get
some feedback... Thanks.
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 1 '06 #4
Richard Heathfield wrote:
Martin Jørgensen said:

Hi,

In continuation of the thread I made "perhaps a stack problem? Long
calculations - strange error?", I think I now got a "stable" error,
meaning that the error always seem to come here now (tried: visual
studio 2005 + linux/macintosh gcc)...

I got 92 lines of complaint from gcc.


Ok, since this problem was just a semi-colon in the wrong place (C is
really a bitch to me sometimes, LOL) I have the feeling that my original
problem perhaps could have been that 2 of my variable arrays was
malloc'ed 2 bytes too small, each (the "perhaps a stack problem?-thing")...
Here are the edited highlights:

main.h:46: warning: declaration of `dx' shadows global declaration
main.h:47: warning: declaration of `dy' shadows global declaration

(lots and lots of similar diagnostics)

.//main.c:32: warning: passing arg 1 of `get_nx_ny_nz' discards qualifiers
from pointer target type
.//main.c:49: warning: passing arg 1 of `quit_program' discards qualifiers
from pointer target type

(lots and lots of similar diagnostics)

When you get a clean compile at a reasonably fascist warning level, come on
back.


Eerhm, please help me get to know how I get so many warnings printed out
so I can fix them... I don't get any if I just type make.

How did you compile (detailed instructions, please)...

I was told that just typing "make" was sufficient (I didn't make the
makefile myself), but I also had the feeling that much more was wrong...

I was actually also wondering why that global variable definitions
didn't work... :-)
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 1 '06 #5
Richard Heathfield wrote:
Martin Jørgensen said: -snip-
When you get a clean compile at a reasonably fascist warning level, come on
back.


Erhm, even better yet: How do I make a/modify my makefile so the program
gets compiled with the highest warning/error-output level every time?

Basically I just want something where I just type "make" and then I see
all (92 lines of or whatever..) warnings/errors?

Then I fix some of them and type "make" again until they're all gone...
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 1 '06 #6
Martin Jørgensen wrote:
Richard Heathfield wrote:
Martin Jørgensen said: -snip-
When you get a clean compile at a reasonably fascist warning level, come on
back.


Erhm, even better yet: How do I make a/modify my makefile so the program
gets compiled with the highest warning/error-output level every time?


The documentation for your compiler will detail the command line flags
needed to set diagnostics level.

If you're using gcc, type info gcc under Linux or download the docs
available from gcc.gnu.org and read them.

A minimal set of switches is -W -Wall -ansi -pedantic. Richard
Heathfield posted recently a set of switches he uses to get even more
checking and diagnostics. Use Google Groups to search for it.

Once you get the command line right, you can then create your makefile.
To do that, GNU make's docs contain a tutorial.
Basically I just want something where I just type "make" and then I see
all (92 lines of or whatever..) warnings/errors?

Then I fix some of them and type "make" again until they're all gone...


As an alternative a graphical IDE might suit your needs, provided it
supplies options to pass to the compiler.

Jun 1 '06 #7
Martin Jørgensen said:
How did you compile (detailed instructions, please)...


I used your makefile (much against my better judgement), but changed:

CFLAGS = $(PROTO_DEFINES) $(STD_DEFINES) -g

to

CFLAGS = $(PROTO_DEFINES) $(STD_DEFINES) -g -W -Wall -ansi -pedantic
-Wformat-nonliteral -Wcast-align -Wpointer-arith -Wbad-function-cast
-Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Winline
-Wundef -Wnested-externs -Wcast-qual -Wshadow -Wconversion -Wwrite-strings
-Wno-conversion -ffloat-store -O2

(all on one line, obviously).

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 1 '06 #8
Martin Jørgensen said:
Richard Heathfield wrote:
Martin Jørgensen said: -snip-
When you get a clean compile at a reasonably fascist warning level, come
on back.


Erhm, even better yet: How do I make a/modify my makefile so the program
gets compiled with the highest warning/error-output level every time?


I have already demonstrated this elsethread.
Basically I just want something where I just type "make" and then I see
all (92 lines of or whatever..) warnings/errors?

Then I fix some of them and type "make" again until they're all gone...


I have a little program called makegen, which generates a makefile on
standard output. The simplest possible usage is:

makegen foo

Its output (which can of course be redirected to a Makefile) is:

CC=gcc
CFLAGS=-W -Wall -ansi -pedantic -Wformat-nonliteral -Wcast-align
-Wpointer-arith -Wbad-function-cast -Wmissing-prototypes
-Wstrict-prototypes -Wmissing-declarations -Winline -Wundef
-Wnested-externs -Wcast-qual -Wshadow -Wconversion -Wwrite-strings
-Wno-conversion -ffloat-store -O2
DFLAGS=-g -pg
foo: foo.o
$(CC) $(CFLAGS) $(DFLAGS) -o foo foo.o
foo.o: foo.c
$(CC) $(CFLAGS) $(DFLAGS) -c -o foo.o foo.c

clean:
rm foo.o
rm foo

install:
cp foo /usr/local/bin

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 1 '06 #9
Martin Jørgensen wrote:
Richard Heathfield wrote:
Martin Jørgensen said:

-snip-
When you get a clean compile at a reasonably fascist warning level,
come on back.


Erhm, even better yet: How do I make a/modify my makefile so the program
gets compiled with the highest warning/error-output level every time?

Basically I just want something where I just type "make" and then I see
all (92 lines of or whatever..) warnings/errors?

Then I fix some of them and type "make" again until they're all gone...


That depends on your compiler and make system (it would not be the same
for all the systems I use). Ask in a group that deals with your tool set.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Jun 1 '06 #10
Richard Heathfield wrote:
Martin Jørgensen said:

How did you compile (detailed instructions, please)...

I used your makefile (much against my better judgement), but changed:

CFLAGS = $(PROTO_DEFINES) $(STD_DEFINES) -g

to

CFLAGS = $(PROTO_DEFINES) $(STD_DEFINES) -g -W -Wall -ansi -pedantic
-Wformat-nonliteral -Wcast-align -Wpointer-arith -Wbad-function-cast
-Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Winline
-Wundef -Wnested-externs -Wcast-qual -Wshadow -Wconversion -Wwrite-strings
-Wno-conversion -ffloat-store -O2

(all on one line, obviously).


Wow... Thanks a lot... The makefile is probably ugly and the code too,
with all those warnings, but now I have a change to fix them...

That was really helpful. Thanks.
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 1 '06 #11
santosh wrote:
Martin Jørgensen wrote:

-snip-
Then I fix some of them and type "make" again until they're all gone...

As an alternative a graphical IDE might suit your needs, provided it
supplies options to pass to the compiler.


Perhaps <OT begin>, but: I already tried some including eclipse which I
didn't like (couldn't watch variable values when I debugged?), DDD and
Anjuta (+ can't remember if I tried kdevelop too).

Anjuta is really nice - the best I've tried so far. I supports "mouse
hovering" over a variable or an expression - that's suberb for me, when
I debug. DDD is also okay (supports a bit lesser "mouse hovering" - not
expressions that span several lines), but I think that at least for some
of these applications I would still need to modify my makefile and now I
have one that works well...

Eclipse wouldn't run without a makefile....

<OT end>
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 1 '06 #12
Flash Gordon wrote:
Martin Jørgensen wrote:
Richard Heathfield wrote:
Martin Jørgensen said:


-snip-
When you get a clean compile at a reasonably fascist warning level,
come on back.

Erhm, even better yet: How do I make a/modify my makefile so the
program gets compiled with the highest warning/error-output level
every time?

Basically I just want something where I just type "make" and then I
see all (92 lines of or whatever..) warnings/errors?

Then I fix some of them and type "make" again until they're all gone...

That depends on your compiler and make system (it would not be the same
for all the systems I use). Ask in a group that deals with your tool set.


Compiler errors aren't compiler specific or at least they should
cover/warn about a language specific problem so I'll post my *language*
problem here and hope somebody bears over with me, since I'm really not
experienced enough to find this solution myself, even though I've
googled for a solution in an hour:

Many places I use:

"if(something goes wrong)" do: "quit_program(__FILE__, __LINE__);
But:

..//main.c:49: warning: passing argument 1 of 'quit_program' discards
qualifiers from pointer target type

And many other places...

***

check_errors.c:

void quit_program(char *filename, int line)
{
int ch;
printf("\n\nSomething went wrong in line %d of file:\n%s!\n\n",
line, filename);
printf("\nPress <ENTER> to finish the program...\n\n");
fflush(stdout);
getchar();
while( ( ch=getchar() ) != '\n'); /* clear keyboard buffer */
exit( EXIT_FAILURE );
}

check_errors.h:

/* quit_program pauses before exiting the program with an error */
void quit_program(char *filename, int line);

main.h:

void quit_program(char *filename, int line);

***

I read on google that this has something to with constness. So I tried
putting a "const"-keyword before "char *filename" and I tried inserting
a "const"-keyword like this: "char * const filename".

1) "const char *filename"
2) "char * const filename"
3) and then I tried combining both methods... "const char * const filename".

I know that when I'm calling the function with "quit_program(__FILE__,
__LINE__);" then ofcourse it must not try to change (char *) = __FILE__.
This is probably what it's complaining about, but how do I tell it
that whatever filename is pointed to should be const? I thought either
of method 1, 2 or 3 would do the job...

I never really cared of this earlier, because I never got warned about
it before... But it would be nice to learn to do it "the proper way".
Since I have 3 files (2 header files + the .c definition-file) that tell
the compiler these arguments, perhaps that's a problem?
TIA.
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 1 '06 #13
Martin Jørgensen wrote:
Flash Gordon wrote: -snip-
1) "const char *filename"
2) "char * const filename"
3) and then I tried combining both methods... "const char * const
filename".


Ups, sorry. Found the error... Method 1 it was... But I had quit_program
declared two places in the same header-file so it seems that if there is
only 1 place were the char* argument isn't const, it complains.... :-(

Damn, there are many warnings/errors... I guess I'll stay up long tonight...
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 1 '06 #14
Martin Jørgensen wrote:
Martin Jørgensen wrote:
Flash Gordon wrote:


-snip-
1) "const char *filename"
2) "char * const filename"
3) and then I tried combining both methods... "const char * const
filename".

Ups, sorry. Found the error... Method 1 it was... But I had quit_program
declared two places in the same header-file so it seems that if there is
only 1 place were the char* argument isn't const, it complains.... :-(

Damn, there are many warnings/errors... I guess I'll stay up long
tonight...

To make more mistakes? Not a good idea... One of the best bug fixing
techniques is a good night's sleep.

--
Ian Collins.
Jun 1 '06 #15


Martin Jørgensen wrote On 06/01/06 16:44,:
Martin Jørgensen wrote:
Flash Gordon wrote:


-snip-

1) "const char *filename"
2) "char * const filename"
3) and then I tried combining both methods... "const char * const
filename".



Ups, sorry. Found the error... Method 1 it was... But I had quit_program
declared two places in the same header-file so it seems that if there is
only 1 place were the char* argument isn't const, it complains.... :-(


(Reading up-thread, it seems the compiler complained about
"discards qualifiers from pointer target type" when passing
__FILE__ to a function taking a plain `char*'.)

Changing the function to take a `const char*' is a good
move, but the compiler's original complaint was a bit off the
mark. __FILE__ expands to a character string literal (says
the Standard, in section 6.10.8), and character string literals
produce arrays of plain `char' (6.4.5), not `const char'. The
compiler is permitted to complain about anything it desires,
but this particular complaint is misleading.

... or is it? String literals are arrays of plain `char'
in C, but in C++ they are arrays of `const char' and the
complaint would make sense. gcc is a compiler for several
different languages, C and C++ among them; is it possible that
you are inadvertently trying to compile C source with the C++
mode of gcc? If so, you'd better start by figuring out how
to operate gcc in C mode, lest you run into even more confusion.
(And if you're actually writing C++ rather than C, you're in
the wrong newsgroup: comp.lang.c++ is where the C++ people are.)

--
Er*********@sun.com

Jun 1 '06 #16
Martin Jørgensen wrote:
Flash Gordon wrote:
Martin Jørgensen wrote:
Richard Heathfield wrote:

Martin Jørgensen said:

-snip-

When you get a clean compile at a reasonably fascist warning level,
come on back.
Erhm, even better yet: How do I make a/modify my makefile so the
program gets compiled with the highest warning/error-output level
every time?

Basically I just want something where I just type "make" and then I
see all (92 lines of or whatever..) warnings/errors?

Then I fix some of them and type "make" again until they're all gone...
That depends on your compiler and make system (it would not be the
same for all the systems I use). Ask in a group that deals with your
tool set.


Compiler errors aren't compiler specific or at least they should


I've no problem with people posting their compiler errors/warnings
together with the code. What I said was that how to drive your tools to
get them is a question better served in another group. Although others
have pointed you in the right direction in this case.
cover/warn about a language specific problem so I'll post my *language*
problem here and hope somebody bears over with me, since I'm really not
experienced enough to find this solution myself, even though I've
googled for a solution in an hour:

Many places I use:

"if(something goes wrong)" do: "quit_program(__FILE__, __LINE__);

But:

.//main.c:49: warning: passing argument 1 of 'quit_program' discards
qualifiers from pointer target type

And many other places...

***

check_errors.c:

void quit_program(char *filename, int line)
This should probably be
void quit_program(const char *filename, int line)
since you are not going to modify what it points to.
{
int ch;
printf("\n\nSomething went wrong in line %d of file:\n%s!\n\n",
line, filename);
printf("\nPress <ENTER> to finish the program...\n\n");
fflush(stdout);
getchar();
while( ( ch=getchar() ) != '\n'); /* clear keyboard buffer */
With both the while loop and the getchar before it the user can end up
having to press enter twice! Also, since you are only checking for \n
and not for EOF this can turn in to an infinite loop!
exit( EXIT_FAILURE );
}

check_errors.h:

/* quit_program pauses before exiting the program with an error */
void quit_program(char *filename, int line);

main.h:

void quit_program(char *filename, int line);
You should not be putting it in both headers! Just put it in
check_errors.h and include that header in all your .c files where you
use the function.
***

I read on google that this has something to with constness. So I tried
putting a "const"-keyword before "char *filename" and I tried inserting
a "const"-keyword like this: "char * const filename".

1) "const char *filename"
This is saying that the chars being pointed to are const. As is
char const *filename
2) "char * const filename"
This is saying that the pointer itself is const, but the chars it points
to are not and so can be modified.
3) and then I tried combining both methods... "const char * const
filename".

I know that when I'm calling the function with "quit_program(__FILE__,
__LINE__);" then ofcourse it must not try to change (char *) = __FILE__.
This is probably what it's complaining about, but how do I tell it that
whatever filename is pointed to should be const? I thought either of
method 1, 2 or 3 would do the job...
Obviously you have to change both header and source file.
I never really cared of this earlier, because I never got warned about
it before... But it would be nice to learn to do it "the proper way".
Since I have 3 files (2 header files + the .c definition-file) that tell
the compiler these arguments, perhaps that's a problem?


That's too many places, you've probably not kept them all in sync.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Jun 1 '06 #17
Martin Jørgensen wrote:
-snip-
Then I fix some of them and type "make" again until they're all gone...


Hi,

I think I've got most under control... After I turned up the
compiler/warning setting, I hope I can make a much better program...
Here is the "problem left-overs" (the problems I don't know what to do
about):

1. The line: "sscanf(line, "%s", &argument);" gives:

warning: format %s expects type char * , but argument 3 has type
char (*)[63u]

Definitions: "char line[64], argument[10];"

Is it afraid that sscanf will put more than 10 characters into argument?
What's the solution?
2. The line: "fseek(fp, 0L, SEEK_SET);" gives:

warning: passing argument 1 of fseek discards qualifiers from pointer
target type

fp comes from an argument because the function that uses fseek looks like:

int integer_load_single_value(const FILE *fp,
const char *input_property)
{
// body with fseek
}

Does anything here have to be const? I would assume that wasn't my
problem to define since the prototyping in stdio.h/stdlib.h should write
if any argument were const's...?
3. I have a file called array_functions.c which has:

void int_fillinnumbers(int fillvalue, int startx,
int stopx, int starty,
int stopy, int **array)
{
int i, j; /* local index variables */

for(j=starty; j<=stopy; j++)
{
for(i=startx; i<=stopx; i++)
array[j][i] = fillvalue; /* integer-fill */
}
}

This function is used different places in the program and is called from
main.c. The problem is:

warning: no previous prototype for int_fillinnumbers

What's it whining about? It don't need another prototype, IMO...
4. I have a #pragma warning because I got some code that does some
nasty/stupid unsigned/signed-tricks so here I would like the compiler to
skip unsigned/signed-checks. But it just writes "ignoring #pragma
warning". Perhaps this is overruled by one of Richard's
-W(...)-arguments to gcc?
The rest of the errors, I'll deal with later (not many left now, when
I've fixed the above 4 "categories")...

Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 1 '06 #18
Eric Sosman wrote:

Martin Jørgensen wrote On 06/01/06 16:44,:
Martin Jørgensen wrote:
Flash Gordon wrote: -snip-

1) "const char *filename"
2) "char * const filename"
3) and then I tried combining both methods... "const char * const
filename".


Ups, sorry. Found the error... Method 1 it was... But I had quit_program
declared two places in the same header-file so it seems that if there is
only 1 place were the char* argument isn't const, it complains.... :-(


(Reading up-thread, it seems the compiler complained about
"discards qualifiers from pointer target type" when passing
__FILE__ to a function taking a plain `char*'.)

Changing the function to take a `const char*' is a good
move, but the compiler's original complaint was a bit off the
mark. __FILE__ expands to a character string literal (says
the Standard, in section 6.10.8), and character string literals
produce arrays of plain `char' (6.4.5), not `const char'.


Correct.
The
compiler is permitted to complain about anything it desires,
but this particular complaint is misleading.

... or is it? String literals are arrays of plain `char'
in C, but in C++ they are arrays of `const char' and the
complaint would make sense. gcc is a compiler for several
different languages, C and C++ among them; is it possible that
you are inadvertently trying to compile C source with the C++
mode of gcc? If so, you'd better start by figuring out how
to operate gcc in C mode, lest you run into even more confusion.
(And if you're actually writing C++ rather than C, you're in
the wrong newsgroup: comp.lang.c++ is where the C++ people are.)


I believe the warning is cause by the compiler switch -Wwrite-strings.
It can be argued that the switch makes the compiler non-conforming
because as you note the standard says string literals are arrays of
char, not arrays of const char. However, it can also be argued that the
compiler is still conforming, since having produced the warning the
compiler still produces code that will work as long as you don't modify
the string literal (attempting to modify it invokes undefined behaviour,
so it doe snot have to work then).

If you write your code using this switch I don't think it is
tremendously hard, but trying to introduce it to some code (badly
written in the case of the specific code I'm think of) can be a lot of work.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Jun 1 '06 #19
Flash Gordon wrote:
Martin Jørgensen wrote:

-snip-
{
int ch;
printf("\n\nSomething went wrong in line %d of
file:\n%s!\n\n", line, filename);
printf("\nPress <ENTER> to finish the program...\n\n");
fflush(stdout);
getchar();
while( ( ch=getchar() ) != '\n'); /* clear keyboard buffer */

With both the while loop and the getchar before it the user can end up
having to press enter twice! Also, since you are only checking for \n
and not for EOF this can turn in to an infinite loop!


Damn... I must look at that later tomorrow/in the weekend... I better
get some rest soon.
exit( EXIT_FAILURE );
}

check_errors.h:

/* quit_program pauses before exiting the program with an error */
void quit_program(char *filename, int line);

main.h:

void quit_program(char *filename, int line);

You should not be putting it in both headers! Just put it in
check_errors.h and include that header in all your .c files where you
use the function.


Damn... Ok, nice to know. I also think I tried it at some moment, but
somehow I went away from it (bug perhaps?) :-)
I read on google that this has something to with constness. So I tried
putting a "const"-keyword before "char *filename" and I tried
inserting a "const"-keyword like this: "char * const filename".

1) "const char *filename"

This is saying that the chars being pointed to are const. As is
char const *filename
2) "char * const filename"

This is saying that the pointer itself is const, but the chars it points
to are not and so can be modified.


Ok, I never remember the difference.
3) and then I tried combining both methods... "const char * const
filename".

I know that when I'm calling the function with "quit_program(__FILE__,
__LINE__);" then ofcourse it must not try to change (char *) =
__FILE__. This is probably what it's complaining about, but how do I
tell it that whatever filename is pointed to should be const? I
thought either of method 1, 2 or 3 would do the job...

Obviously you have to change both header and source file.


It's working now...
I never really cared of this earlier, because I never got warned about
it before... But it would be nice to learn to do it "the proper way".
Since I have 3 files (2 header files + the .c definition-file) that
tell the compiler these arguments, perhaps that's a problem?

That's too many places, you've probably not kept them all in sync.


It's okay now, but I better clean it up so I don't have to keep
everything in sync in the future as the program grows bigger and bigger
(now 150 kb - I didn't upload all the code, only the first part until
the "mysterious error" came)...
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 1 '06 #20
Martin Jørgensen said:
1. The line: "sscanf(line, "%s", &argument);" gives:

warning: format %s expects type char * , but argument 3 has type
char (*)[63u]

Definitions: "char line[64], argument[10];"

Is it afraid that sscanf will put more than 10 characters into argument?
What's the solution?
if(sscanf(line, "%9s", argument) == 1)
{

Your spurious & on &argument means you're passing char (*)[10] - a pointer
to an array of 10 char - instead of char *, which is what you get when you
pass the name of an array of char to a function.
2. The line: "fseek(fp, 0L, SEEK_SET);" gives:

warning: passing argument 1 of fseek discards qualifiers from pointer
target type

fp comes from an argument because the function that uses fseek looks like:

int integer_load_single_value(const FILE *fp,
Drop the const from fp. The fseek function needs to be able to modify the
file position indicator member of the object pointed to by fp.
3. I have a file called array_functions.c which has:

void int_fillinnumbers(int fillvalue, int startx,
int stopx, int starty,
int stopy, int **array)
{
int i, j; /* local index variables */

for(j=starty; j<=stopy; j++)
{
for(i=startx; i<=stopx; i++)
array[j][i] = fillvalue; /* integer-fill */
}
}

This function is used different places in the program and is called from
main.c. The problem is:

warning: no previous prototype for int_fillinnumbers

What's it whining about? It don't need another prototype, IMO...
If the function is called only from within the translation unit in which it
is defined, and is called only /after/ the function definition, then you
can ignore the warning. Otherwise, but this:

void int_fillinnumbers(int fillvalue, int startx,
int stopx, int starty,
int stopy, int **array);

in a header, and #include that header in all translation units that contain
calls to the function. It is also wise to #include it in the translation
unit where the function is defined, as this will catch any mods that are
done to the definition which have not been reflected in the header.
4. I have a #pragma warning because I got some code that does some
nasty/stupid unsigned/signed-tricks so here I would like the compiler to
skip unsigned/signed-checks. But it just writes "ignoring #pragma
warning".


#pragmas are, by definition, non-portable (with one trivial C99 exception
which I'll ignore as irrelevant on this occasion).

The fix here is: don't use nasty/stupid unsigned/signed-tricks!

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 1 '06 #21
Richard Heathfield wrote:
Martin Jørgensen said:

Hi, there... I almost eliminated all errors/warnings. Only got a few left.
1. The line: "sscanf(line, "%s", &argument);" gives:

warning: format %s expects type char * , but argument 3 has type
char (*)[63u]

Definitions: "char line[64], argument[10];"

Is it afraid that sscanf will put more than 10 characters into argument?
What's the solution?

if(sscanf(line, "%9s", argument) == 1)
{

Your spurious & on &argument means you're passing char (*)[10] - a pointer
to an array of 10 char - instead of char *, which is what you get when you
pass the name of an array of char to a function.


Thanks a lot... Actually I forgot... I had #defined something called
maxsize or something. Suppose I had "#define maxsize 10", could I then
write if(sscanf(line, "%(maxsize-1)s", argument) == 1) ? That would be
better...
2. The line: "fseek(fp, 0L, SEEK_SET);" gives:

warning: passing argument 1 of fseek discards qualifiers from pointer
target type

fp comes from an argument because the function that uses fseek looks like:

int integer_load_single_value(const FILE *fp,

Drop the const from fp. The fseek function needs to be able to modify the
file position indicator member of the object pointed to by fp.


Much better.
3. I have a file called array_functions.c which has:

void int_fillinnumbers(int fillvalue, int startx,
int stopx, int starty,
int stopy, int **array)
{
int i, j; /* local index variables */

for(j=starty; j<=stopy; j++)
{
for(i=startx; i<=stopx; i++)
array[j][i] = fillvalue; /* integer-fill */
}
}

This function is used different places in the program and is called from
main.c. The problem is:

warning: no previous prototype for int_fillinnumbers

What's it whining about? It don't need another prototype, IMO...

If the function is called only from within the translation unit in which it
is defined, and is called only /after/ the function definition, then you
can ignore the warning. Otherwise, but this:

void int_fillinnumbers(int fillvalue, int startx,
int stopx, int starty,
int stopy, int **array);


Damn... I also had that............... I thought....

I just accidentally deleted the semi-colon and thought it was still
there, therefore I didn't understand it before...
in a header, and #include that header in all translation units that contain
calls to the function. It is also wise to #include it in the translation
unit where the function is defined, as this will catch any mods that are
done to the definition which have not been reflected in the header.

4. I have a #pragma warning because I got some code that does some
nasty/stupid unsigned/signed-tricks so here I would like the compiler to
skip unsigned/signed-checks. But it just writes "ignoring #pragma
warning".

#pragmas are, by definition, non-portable (with one trivial C99 exception
which I'll ignore as irrelevant on this occasion).

The fix here is: don't use nasty/stupid unsigned/signed-tricks!


But I don't think I can't avoid it, as I'm using some old code which I
don't know how to rewrite... The messages are: "warning: comparison
between signed and unsigned", and I tried to debug this sh*t, but it's
really nasty so I didn't understood it. For instance it decremented an
unsigned variable below 0, so I dare not even cast any of it to the same
type if it makes any problems...

But hey, let me hear - perhaps I can explicitly cast and get rid of the
warnings, without losing functionality: I have this:

for (i=1;i<=left;i++)

"i" is unsigned int, "left" is integer. Would it be absolutely safe to
rewrite the line to:

1. for (i=1;i<= (unsigned) left;i++)

or

2. for ((int) i=1;i<= left;i++)

And then get the same nasty bit-fiddling functionality and no warning?
I also have
if(l < mm) l++;

where "l" is unsigned long, "mm" is int...


And then I have an output-routine that prints a 2D-array of type double **:

void double_printout(int startcol, int stopcol,
int startrow, int stoprow,
double **array, char *indent,
unsigned digits)
{
int i, j; /* local index variables */
char formatstring[] = "-> %8.2f ";

printf("\n");

if(digits >=8 || digits <0)
{
printf("ERROR! Can't print that number of digits.\n");
quit_program(__FILE__, __LINE__);
}

formatstring[6] = (char)('0'+ digits);

for(j=startrow; j<=stoprow; j++)
{
printf("\n%2d: %s", j, indent);
for(i=startcol; i<=stopcol; i++)
printf( ("%s", formatstring), array[j][i]); /*<= WARNING!*/
}
printf("\n\n");
}
I know that's probably considered ugly coding but I wanted to pass an
unsigned "digits"-value, that determines how many decimal places after
the comma should be included in the output... Therefore I had to modify
the "formatstring", which is passed as an argument to printf().

The message is:

"warning: format not a string literal, argument types not checked"

I guess it's trying to tell me that "formatstring" is not a string
literal. But I don't know how to fix the problem, then and still get
this "number of digits passed into argument"-behaviour.
Last problem (I think / I hope - it looks much better now):

This is probably also a bit nasty, but I need the program to generate a
number of output-files that are consecutive numbered like
"file0000.vtk", "file0001.vtk", "file0002.vtk", "file0003.vtk",
"file0004.vtk", ......., "file0009.vtk", "file0010.vtk", "file0011.vtk",
....... "file0099.vtk", "file0100.vtk"....

Therefore I needed to figure out how many digits the "counter"-variable
took up. I found a good method I think... At least I couldn't find a
better method. I used:

/* calculate number of leading zero's for 3-digit numbers up to 999 */
counter = 2 - (int) log10( (double) *output_filestep );

Let's try it: output_filestep (is an int AFAIR) = 5. log(5) = 0.7. We
make it (cast it to become) an integer, so it becomes (int) 0.7 => 0.
Counter = 2, because then we need to fill in two zero, i.e. "file00" +
"5". My problem is:

"warning: cast from function call of type double to non-matching type
int"

I thought I already casted it to an integer with the (int) part and
therefore I thought I explicitly told the compiler not to complain about
this cast. How do I fix it/make the warning disappear?

And that's it... The compiling process would really look beautiful if I
could get rid of the last warnings, if you know what I mean :-) :-)
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 3 '06 #22
Martin Jørgensen said:

<snip>
I had #defined something called
maxsize or something. Suppose I had "#define maxsize 10", could I then
write if(sscanf(line, "%(maxsize-1)s", argument) == 1) ? That would be
better...
Well, you can do this:

#define STR(x) #x
#define XSTR(x) STR(x)

#define maxsize 9

char argument[maxsize + 1];

if(sscanf(line, "%" XSTR(maxsize)"s", argument))
{

but it's a bit ugly. Personally, I prefer to avoid *scanf completely.

The fix here is: don't use nasty/stupid unsigned/signed-tricks!


But I don't think I can't avoid it, as I'm using some old code which I
don't know how to rewrite... The messages are: "warning: comparison
between signed and unsigned",


Sometimes you can put up with these warnings. It depends how close to the
edge you're going to get. If you're comparing si with ui and both of them
are only going to have values that are inside the range of both (i.e. 0 to
INT_MAX), then it's no big deal.

I don't recommend adding casts in an attempt to hide the problem. The
diagnostics are useful in reminding you that this problem exists and
requires caution. Clean compiles are all very well, and indeed very
laudable, but not (IMHO) at the expense of clarity, correctness, and
caution. The real fix is not to use those tricks - but if you can't avoid
that because you're not confident about editing the code, then you might be
better off leaving the warnings where you can see them, where they will
remind you that you have a few minor dragons in your code which must be
carefully fed and kept on a leash.

<snip>
The message is:

"warning: format not a string literal, argument types not checked"

I guess it's trying to tell me that "formatstring" is not a string
literal. But I don't know how to fix the problem, then and still get
this "number of digits passed into argument"-behaviour.
Well, you can't. All the compiler is telling you is "I'd love to check these
% thingies for you, but hey, the string can change at runtime, so there
isn't much point". So it's a heads-up that you should be extra careful to
ensure that the % fields match up correctly by type, to the things you want
to print. No big deal.


Last problem (I think / I hope - it looks much better now):

This is probably also a bit nasty, but I need the program to generate a
number of output-files that are consecutive numbered like
"file0000.vtk", "file0001.vtk", "file0002.vtk", "file0003.vtk",
"file0004.vtk", ......., "file0009.vtk", "file0010.vtk", "file0011.vtk",
...... "file0099.vtk", "file0100.vtk"....

Therefore I needed to figure out how many digits the "counter"-variable
took up. I found a good method I think... At least I couldn't find a
better method. I used:

/* calculate number of leading zero's for 3-digit numbers up to 999 */
counter = 2 - (int) log10( (double) *output_filestep );


Why bother? Why not let sprintf do it for you?

Decide how many digits you want altogether (in your above examples, you are
using four digits altogether in each filename), and just do this:

fieldwidth = 4; /* or whatever */
sprintf(filename, "file%0*d.vtk", fieldwidth, *output_filestep);

or, if you are confident that you always want exactly four digits, just do:

sprintf(filename, "file%04d.vtk", *output_filestep);

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 3 '06 #23
On Sat, 03 Jun 2006 02:04:01 +0200, Martin Jørgensen
<un*********@spam.jay.net> wrote:
Richard Heathfield wrote:
Martin Jørgensen said:
snip

Please learn to trim your quotes.
4. I have a #pragma warning because I got some code that does some
nasty/stupid unsigned/signed-tricks so here I would like the compiler to
skip unsigned/signed-checks. But it just writes "ignoring #pragma
warning".

#pragmas are, by definition, non-portable (with one trivial C99 exception
which I'll ignore as irrelevant on this occasion).

The fix here is: don't use nasty/stupid unsigned/signed-tricks!


But I don't think I can't avoid it, as I'm using some old code which I
don't know how to rewrite... The messages are: "warning: comparison
between signed and unsigned", and I tried to debug this sh*t, but it's
really nasty so I didn't understood it. For instance it decremented an
unsigned variable below 0, so I dare not even cast any of it to the same
type if it makes any problems...

But hey, let me hear - perhaps I can explicitly cast and get rid of the
warnings, without losing functionality: I have this:

for (i=1;i<=left;i++)

"i" is unsigned int, "left" is integer. Would it be absolutely safe to


Why not create a new int ii and use that instead of i?
rewrite the line to:

1. for (i=1;i<= (unsigned) left;i++)
Can left ever be negative? Can left ever be UINT_MAX?

or

2. for ((int) i=1;i<= left;i++)
Can left ever be between INT_MAX and UINT_MAX?

And then get the same nasty bit-fiddling functionality and no warning?
I also have
if(l < mm) l++;

where "l" is unsigned long, "mm" is int...


And then I have an output-routine that prints a 2D-array of type double **:
Do you really have a 2D array of pointer to pointer to double? Or do
you have a pointer to pointer to double which you are treating as a 2D
array.

void double_printout(int startcol, int stopcol,
int startrow, int stoprow,
double **array, char *indent,
unsigned digits)
{
int i, j; /* local index variables */
char formatstring[] = "-> %8.2f ";

printf("\n");

if(digits >=8 || digits <0)
digits is unsigned. Can it ever be less than 0?
{
printf("ERROR! Can't print that number of digits.\n");
quit_program(__FILE__, __LINE__);
}

formatstring[6] = (char)('0'+ digits);
What do you think the cast does? Is digits always less than 10?

for(j=startrow; j<=stoprow; j++)
{
printf("\n%2d: %s", j, indent);
for(i=startcol; i<=stopcol; i++)
printf( ("%s", formatstring), array[j][i]); /*<= WARNING!*/
What do you think the
"%s",
does?
}
printf("\n\n");
}
I know that's probably considered ugly coding but I wanted to pass an
unsigned "digits"-value, that determines how many decimal places after
the comma should be included in the output... Therefore I had to modify
the "formatstring", which is passed as an argument to printf().

The message is:

"warning: format not a string literal, argument types not checked"

I guess it's trying to tell me that "formatstring" is not a string
literal. But I don't know how to fix the problem, then and still get
this "number of digits passed into argument"-behaviour.
Check your documentation to see if you can turn this warning off.


Last problem (I think / I hope - it looks much better now):

This is probably also a bit nasty, but I need the program to generate a
number of output-files that are consecutive numbered like
"file0000.vtk", "file0001.vtk", "file0002.vtk", "file0003.vtk",
"file0004.vtk", ......., "file0009.vtk", "file0010.vtk", "file0011.vtk",
...... "file0099.vtk", "file0100.vtk"....

Therefore I needed to figure out how many digits the "counter"-variable
took up. I found a good method I think... At least I couldn't find a
better method. I used:

/* calculate number of leading zero's for 3-digit numbers up to 999 */
counter = 2 - (int) log10( (double) *output_filestep );
What do you think the cast to double does?

Let's try it: output_filestep (is an int AFAIR) = 5. log(5) = 0.7. We
make it (cast it to become) an integer, so it becomes (int) 0.7 => 0.
Counter = 2, because then we need to fill in two zero, i.e. "file00" +
"5". My problem is:

"warning: cast from function call of type double to non-matching type
int"

I thought I already casted it to an integer with the (int) part and
therefore I thought I explicitly told the compiler not to complain about
this cast. How do I fix it/make the warning disappear?


This warning makes no sense to me. You are deliberately casting the
return from log10 to force the arithmetic to be performed in int mode
as opposed to the normal double mode. Check the docs again for a way
to suppress it.

Remove del for email
Jun 3 '06 #24
Richard Heathfield wrote:
Martin Jørgensen said:

<snip>
I had #defined something called
maxsize or something. Suppose I had "#define maxsize 10", could I then
write if(sscanf(line, "%(maxsize-1)s", argument) == 1) ? That would be
better...

Well, you can do this:

#define STR(x) #x
#define XSTR(x) STR(x)

#define maxsize 9

char argument[maxsize + 1];

if(sscanf(line, "%" XSTR(maxsize)"s", argument))
{

but it's a bit ugly. Personally, I prefer to avoid *scanf completely.


Yes, that's ugly... I think I should just search/replace maxsize and
replace it with 10, so the %9s part is okay. Would you use:

#define MAXLINE 10
fgets(line, MAXLINE, fp)

Instead of scanf?
The fix here is: don't use nasty/stupid unsigned/signed-tricks!


But I don't think I can't avoid it, as I'm using some old code which I
don't know how to rewrite... The messages are: "warning: comparison
between signed and unsigned",

Sometimes you can put up with these warnings. It depends how close to the
edge you're going to get. If you're comparing si with ui and both of them
are only going to have values that are inside the range of both (i.e. 0 to
INT_MAX), then it's no big deal.


Ok. AFAIR: It did some crazy/stupid crap with decrementing an *unsigned*
counter to below 0 somewhere (that can't fit in a signed int, I guess).
But perhaps I could make it a long integer? hmm... Or I just stick with
those 6-7 warnings...
I don't recommend adding casts in an attempt to hide the problem. The
diagnostics are useful in reminding you that this problem exists and
requires caution. Clean compiles are all very well, and indeed very
laudable, but not (IMHO) at the expense of clarity, correctness, and
caution. The real fix is not to use those tricks - but if you can't avoid
that because you're not confident about editing the code, then you might be
better off leaving the warnings where you can see them, where they will
remind you that you have a few minor dragons in your code which must be
carefully fed and kept on a leash.


I think you're right... I just do that for now.
The message is:

"warning: format not a string literal, argument types not checked"

I guess it's trying to tell me that "formatstring" is not a string
literal. But I don't know how to fix the problem, then and still get
this "number of digits passed into argument"-behaviour.

Well, you can't. All the compiler is telling you is "I'd love to check these
% thingies for you, but hey, the string can change at runtime, so there
isn't much point". So it's a heads-up that you should be extra careful to
ensure that the % fields match up correctly by type, to the things you want
to print. No big deal.


Ok, but I can't make a clean compilation then (unless I change that part)...
Last problem (I think / I hope - it looks much better now):

This is probably also a bit nasty, but I need the program to generate a
number of output-files that are consecutive numbered like
"file0000.vtk", "file0001.vtk", "file0002.vtk", "file0003.vtk",
"file0004.vtk", ......., "file0009.vtk", "file0010.vtk", "file0011.vtk",
...... "file0099.vtk", "file0100.vtk"....

Therefore I needed to figure out how many digits the "counter"-variable
took up. I found a good method I think... At least I couldn't find a
better method. I used:

/* calculate number of leading zero's for 3-digit numbers up to 999 */
counter = 2 - (int) log10( (double) *output_filestep );

Why bother? Why not let sprintf do it for you?

Decide how many digits you want altogether (in your above examples, you are
using four digits altogether in each filename), and just do this:

fieldwidth = 4; /* or whatever */
sprintf(filename, "file%0*d.vtk", fieldwidth, *output_filestep);

or, if you are confident that you always want exactly four digits, just do:

sprintf(filename, "file%04d.vtk", *output_filestep);


Dough! Thanks. Look good - I'll try that :-)
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 3 '06 #25
Barry Schwarz wrote:
On Sat, 03 Jun 2006 02:04:01 +0200, Martin Jørgensen
<un*********@spam.jay.net> wrote:

-snip-
rewrite the line to:

1. for (i=1;i<= (unsigned) left;i++)

Can left ever be negative? Can left ever be UINT_MAX?


AFAIR: If you say:

unsigned left = 0;
left--;

Then we get a very big unsigned number that can't fit in a integer. So I
think left is bigger than UINT_MAX, but I'm not sure as I didn't look at
that code in about 1 month and remember that it did some stupid
unsigned/signed tricks like left-- to below 0, even though it's unsigned.

-snip-
And then I have an output-routine that prints a 2D-array of type double **:

Do you really have a 2D array of pointer to pointer to double? Or do
you have a pointer to pointer to double which you are treating as a 2D
array.


Erhm. I think I have a pointer to pointer to double (dynamically
allocated - not static), which I treat as a 2D array. So perhaps writing
a 2D-array of type double ** is incorrect?

Anyway, the function argument is double **, right? I don't get any
compiler warnings/problems, so I think the code is okay.
void double_printout(int startcol, int stopcol,
int startrow, int stoprow,
double **array, char *indent,
unsigned digits)
{
int i, j; /* local index variables */
char formatstring[] = "-> %8.2f ";

printf("\n");

if(digits >=8 || digits <0)

digits is unsigned. Can it ever be less than 0?


No, correct. It was integer before. I just thought it was nice to keep
it if I suddenly changed it back to an integer (suppose I should pass
digits to another function that took "digits" as an integer), but I just
found out that the compiler with this high warning level complains.

I just removed || digits <0, to get rid of the warning.
{
printf("ERROR! Can't print that number of digits.\n");
quit_program(__FILE__, __LINE__);
}

formatstring[6] = (char)('0'+ digits);

What do you think the cast does? Is digits always less than 10?


It should be as I just did an "if(digits >=8)" quit. Actually I can't
remember if I inserted the cast to get rid of a compiler warning or not.
But formatstring consists of chars and the righthandside gives what...?
An integer? Should I remove the cast?
for(j=startrow; j<=stoprow; j++)
{
printf("\n%2d: %s", j, indent);
for(i=startcol; i<=stopcol; i++)
printf( ("%s", formatstring), array[j][i]); /*<= WARNING!*/

What do you think the
"%s",
does?


Hmm... Yes, that's not too good... Perhaps nothing? AFAIR I deleted it
late yesterday, due to a compiler warning.
-snip-
Last problem (I think / I hope - it looks much better now):

This is probably also a bit nasty, but I need the program to generate a
number of output-files that are consecutive numbered like
"file0000.vtk", "file0001.vtk", "file0002.vtk", "file0003.vtk",
"file0004.vtk", ......., "file0009.vtk", "file0010.vtk", "file0011.vtk",
...... "file0099.vtk", "file0100.vtk"....

Therefore I needed to figure out how many digits the "counter"-variable
took up. I found a good method I think... At least I couldn't find a
better method. I used:

/* calculate number of leading zero's for 3-digit numbers up to 999 */
counter = 2 - (int) log10( (double) *output_filestep );

What do you think the cast to double does?


Makes sure that log10 gets a double-parameter as *output_filestep isn't
a double, but either unsigned int/int.
Let's try it: output_filestep (is an int AFAIR) = 5. log(5) = 0.7. We
make it (cast it to become) an integer, so it becomes (int) 0.7 => 0.
Counter = 2, because then we need to fill in two zero, i.e. "file00" +
"5". My problem is:

"warning: cast from function call of type double to non-matching type
int"

I thought I already casted it to an integer with the (int) part and
therefore I thought I explicitly told the compiler not to complain about
this cast. How do I fix it/make the warning disappear?

This warning makes no sense to me. You are deliberately casting the
return from log10 to force the arithmetic to be performed in int mode
as opposed to the normal double mode. Check the docs again for a way
to suppress it.


Perhaps I needed more parenthesis... But Richard came with a much better
solution than this code, so it doesn't matter now.
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 3 '06 #26
On Sat, 03 Jun 2006 17:21:46 +0200, Martin Jørgensen
<un*********@spam.jay.net> wrote:
Barry Schwarz wrote:
On Sat, 03 Jun 2006 02:04:01 +0200, Martin Jørgensen
<un*********@spam.jay.net> wrote:-snip-
rewrite the line to:

1. for (i=1;i<= (unsigned) left;i++)

Can left ever be negative? Can left ever be UINT_MAX?


AFAIR: If you say:

unsigned left = 0;
left--;

Then we get a very big unsigned number that can't fit in a integer. So I
think left is bigger than UINT_MAX, but I'm not sure as I didn't look at
that code in about 1 month and remember that it did some stupid
unsigned/signed tricks like left-- to below 0, even though it's unsigned.


The point is that if left is negative, without the cast your for loop
executes 0 times. If you follow your suggestion and insert the cast,
you have changed the performance of the program for the sake of
eliminating a warning.

-snip-
And then I have an output-routine that prints a 2D-array of type double **:

Do you really have a 2D array of pointer to pointer to double? Or do
you have a pointer to pointer to double which you are treating as a 2D
array.


Erhm. I think I have a pointer to pointer to double (dynamically
allocated - not static), which I treat as a 2D array. So perhaps writing
a 2D-array of type double ** is incorrect?


That was the point.

Anyway, the function argument is double **, right? I don't get any
compiler warnings/problems, so I think the code is okay.
void double_printout(int startcol, int stopcol,
int startrow, int stoprow,
double **array, char *indent,
unsigned digits)
{
int i, j; /* local index variables */
char formatstring[] = "-> %8.2f ";

printf("\n");

if(digits >=8 || digits <0)

digits is unsigned. Can it ever be less than 0?


No, correct. It was integer before. I just thought it was nice to keep
it if I suddenly changed it back to an integer (suppose I should pass
digits to another function that took "digits" as an integer), but I just
found out that the compiler with this high warning level complains.

I just removed || digits <0, to get rid of the warning.
{
printf("ERROR! Can't print that number of digits.\n");
quit_program(__FILE__, __LINE__);
}

formatstring[6] = (char)('0'+ digits);

What do you think the cast does? Is digits always less than 10?


It should be as I just did an "if(digits >=8)" quit. Actually I can't
remember if I inserted the cast to get rid of a compiler warning or not.
But formatstring consists of chars and the righthandside gives what...?
An integer? Should I remove the cast?


If your code had been
formatstring[6] = '0';
would you have inserted the cast? The RHS of both statements have the
same type.
for(j=startrow; j<=stoprow; j++)
{
printf("\n%2d: %s", j, indent);
for(i=startcol; i<=stopcol; i++)
printf( ("%s", formatstring), array[j][i]); /*<= WARNING!*/

What do you think the
"%s",
does?


Hmm... Yes, that's not too good... Perhaps nothing? AFAIR I deleted it
late yesterday, due to a compiler warning.
-snip-
Last problem (I think / I hope - it looks much better now):

This is probably also a bit nasty, but I need the program to generate a
number of output-files that are consecutive numbered like
"file0000.vtk", "file0001.vtk", "file0002.vtk", "file0003.vtk",
"file0004.vtk", ......., "file0009.vtk", "file0010.vtk", "file0011.vtk",
...... "file0099.vtk", "file0100.vtk"....

Therefore I needed to figure out how many digits the "counter"-variable
took up. I found a good method I think... At least I couldn't find a
better method. I used:

/* calculate number of leading zero's for 3-digit numbers up to 999 */
counter = 2 - (int) log10( (double) *output_filestep );

What do you think the cast to double does?


Makes sure that log10 gets a double-parameter as *output_filestep isn't
a double, but either unsigned int/int.


If there is a prototype in scope for log10 and if the parameter has
type double, then the argument will be converted to double implicitly
if possible. If not possible, you have a syntax error which you
really want to know about. All the cast does is prohibit the compiler
from helping you. (It is the same as casting the return from malloc.)
Let's try it: output_filestep (is an int AFAIR) = 5. log(5) = 0.7. We
make it (cast it to become) an integer, so it becomes (int) 0.7 => 0.
Counter = 2, because then we need to fill in two zero, i.e. "file00" +
"5". My problem is:

"warning: cast from function call of type double to non-matching type
int"

I thought I already casted it to an integer with the (int) part and
therefore I thought I explicitly told the compiler not to complain about
this cast. How do I fix it/make the warning disappear?

This warning makes no sense to me. You are deliberately casting the
return from log10 to force the arithmetic to be performed in int mode
as opposed to the normal double mode. Check the docs again for a way
to suppress it.


Perhaps I needed more parenthesis... But Richard came with a much better
solution than this code, so it doesn't matter now.
Best regards
Martin Jørgensen

Remove del for email
Jun 3 '06 #27
Martin Jørgensen said:
Richard Heathfield wrote:

[...] but it's a bit ugly. Personally, I prefer to avoid *scanf
completely.


Yes, that's ugly... I think I should just search/replace maxsize and
replace it with 10, so the %9s part is okay. Would you use:

#define MAXLINE 10
fgets(line, MAXLINE, fp)

Instead of scanf?


Well, yes and no. No, in that I'd want to check the return value of the
function. No, in that I wouldn't actually use fgets either, probably. But
yes, some kind of function that grabs the text a line at a time - which
even fgets can do if no line is longer than the buffer you supply. So yes,
you're on the right track.

Having read it, then I'd pick it apart myself, using the various str*
parsing routines.

<snip>

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jun 3 '06 #28
Flash Gordon wrote:
Martin Jørgensen wrote:

-snip-
{
int ch;
printf("\n\nSomething went wrong in line %d of
file:\n%s!\n\n", line, filename);
printf("\nPress <ENTER> to finish the program...\n\n");
fflush(stdout);
getchar();
while( ( ch=getchar() ) != '\n'); /* clear keyboard buffer */

With both the while loop and the getchar before it the user can end up
having to press enter twice! Also, since you are only checking for \n
and not for EOF this can turn in to an infinite loop!


Would this be bullet-proof?
/* quit_program pauses before exiting the program with an error */
void quit_program(char *filename, int line)
{
int ch;
printf("\n\nSomething went wrong in line %d of file:\n%s!\n\n",
line, filename);
printf("\nPress <ENTER> to finish the program...\n\n");
fflush(stdout);
while( ( ch=getchar() ) != '\n' && ch != EOF);
exit( EXIT_FAILURE );
}

I always hate those keyboard-functions... Is there any chance there
would still be something left in the keyboard buffer and is it something
I should do anything to avoid?
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 4 '06 #29
Richard Heathfield wrote:
Martin Jørgensen said:

Richard Heathfield wrote:
[...] but it's a bit ugly. Personally, I prefer to avoid *scanf
completely.


Yes, that's ugly... I think I should just search/replace maxsize and
replace it with 10, so the %9s part is okay. Would you use:

#define MAXLINE 10
fgets(line, MAXLINE, fp)

Instead of scanf?

Well, yes and no. No, in that I'd want to check the return value of the
function. No, in that I wouldn't actually use fgets either, probably. But
yes, some kind of function that grabs the text a line at a time - which
even fgets can do if no line is longer than the buffer you supply. So yes,
you're on the right track.

Having read it, then I'd pick it apart myself, using the various str*
parsing routines.


Ok... I have something I can go and think about...

The good news is that the only warnings I got left is the:

- unsigned/signed warning +
- the "format not a string literal, argument types not checked"-warnings

(that came because of this "formatstring[6] = (char)('0'+ digits);" and
then formatstring was passed to printf).

I don't think I can do anything about those right now...
There were also some "uninitialized variable" warnings which I fixed,
even though it wasn't strictly necessary (the program would have gone
into quit_program so those variables would never have been used in that
case)...

It makes me sleep much better in the night with all those warnings
fixed.... I must have fixed a couple of hundred warning messages lately :-)

So thanks again :-)
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 4 '06 #30
Barry Schwarz wrote:
On Sat, 03 Jun 2006 17:21:46 +0200, Martin Jørgensen
<un*********@spam.jay.net> wrote:

-snip-
And then I have an output-routine that prints a 2D-array of type double **:
Do you really have a 2D array of pointer to pointer to double? Or do
you have a pointer to pointer to double which you are treating as a 2D
array.


Erhm. I think I have a pointer to pointer to double (dynamically
allocated - not static), which I treat as a 2D array. So perhaps writing
a 2D-array of type double ** is incorrect?

That was the point.


Hmm. What exactly is wrong with writing that?

-snip-
{
printf("ERROR! Can't print that number of digits.\n");
quit_program(__FILE__, __LINE__);
}

formatstring[6] = (char)('0'+ digits);
What do you think the cast does? Is digits always less than 10?


It should be as I just did an "if(digits >=8)" quit. Actually I can't
remember if I inserted the cast to get rid of a compiler warning or not.
But formatstring consists of chars and the righthandside gives what...?
An integer? Should I remove the cast?

If your code had been
formatstring[6] = '0';
would you have inserted the cast? The RHS of both statements have the
same type.


Then you're saying that I should just remove the cast, as both sides are
the same type... Hmm. Ok.

=snip-
/* calculate number of leading zero's for 3-digit numbers up to 999 */
counter = 2 - (int) log10( (double) *output_filestep );
What do you think the cast to double does?


Makes sure that log10 gets a double-parameter as *output_filestep isn't
a double, but either unsigned int/int.

If there is a prototype in scope for log10 and if the parameter has
type double, then the argument will be converted to double implicitly
if possible. If not possible, you have a syntax error which you
really want to know about. All the cast does is prohibit the compiler
from helping you. (It is the same as casting the return from malloc.)


I learned not to cast the return of malloc from this group... And it
looks like I now learned that it would automatically perform an implicit
cast from int to double, which I might not have known before... Actually
I thought I inserted it because I got a warning, but if you say so I
must have been using it without even trying to compile the code without
the cast.
Let's try it: output_filestep (is an int AFAIR) = 5. log(5) = 0.7. We
make it (cast it to become) an integer, so it becomes (int) 0.7 => 0.
Counter = 2, because then we need to fill in two zero, i.e. "file00" +
"5". My problem is:

"warning: cast from function call of type double to non-matching type
int"

I thought I already casted it to an integer with the (int) part and
therefore I thought I explicitly told the compiler not to complain about
this cast. How do I fix it/make the warning disappear?
This warning makes no sense to me. You are deliberately casting the
return from log10 to force the arithmetic to be performed in int mode
as opposed to the normal double mode. Check the docs again for a way
to suppress it.


BTW: If you or anyone else find out why this gave an error, it could be
interesting to know (I hope I didn't gave a wrong problem description
here or misread the warning-linenumber?):

counter = 2 - (int) log10( (double) *output_filestep );

"warning: cast from function call of type double to non-matching type
int"... It is actually strange...???

*output_filestep = pointer to int.
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 4 '06 #31
Martin Jørgensen <un*********@spam.jay.net> writes:
[...]
I learned not to cast the return of malloc from this group... And it
looks like I now learned that it would automatically perform an
implicit cast from int to double, which I might not have known
before... Actually I thought I inserted it because I got a warning,
but if you say so I must have been using it without even trying to
compile the code without the cast.


There is no such thing as an "implicit cast", though it's a common
(and incorrect) phrase.

A cast is an operator, consisting of a type name in parentheses,
applied to some expression. A cast operator specifies a conversion.
A conversion can be either explicit (i.e., a cast) or implicit (e.g.,
"x = y", where x and y are of different numeric types).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jun 4 '06 #32
Martin Jørgensen wrote:
Ok... I have something I can go and think about...

The good news is that the only warnings I got left is the:

- unsigned/signed warning +
- the "format not a string literal, argument types not checked"-warnings

(that came because of this "formatstring[6] = (char)('0'+ digits);" and
then formatstring was passed to printf).


You should be able to fix the format string by replacing the number in
the format string with a * and then supplying the number as an int
argument so you would have something like this:

printf( "-> %8.*f", (int)digits, array[j][i]);

Kevin Bagust.
Jun 4 '06 #33
Kevin Bagust wrote:
Martin Jørgensen wrote:
Ok... I have something I can go and think about...

The good news is that the only warnings I got left is the:

- unsigned/signed warning +
- the "format not a string literal, argument types not checked"-warnings

(that came because of this "formatstring[6] = (char)('0'+ digits);"
and then formatstring was passed to printf).

You should be able to fix the format string by replacing the number in
the format string with a * and then supplying the number as an int
argument so you would have something like this:

printf( "-> %8.*f", (int)digits, array[j][i]);


Oh, thanks a lot - that's great. I just looked it up in my book and it
seems like this should work without any difficulties at all. So I'll
implement it later.
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Jun 4 '06 #34

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.