By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,257 Members | 2,812 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,257 IT Pros & Developers. It's quick & easy.

Am I doing something wrong with printf() here?

P: n/a
Hello, I have two code snippets I want you to look at. My program compiles
without warnings (warning level set to max, gcc 3.4.3) with either snippet
but the latter one causes a segfault at run-time. I know it contains
non-standard constructs (using the MySql C api) but I wanted to know if it's
printf() I'm misuing. Here are the snippets:

/* m is of type MYSQL* */
unsigned int code = mysql_errno(m);
const char *description = mysql_error(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", code, description);
}

This snippet doesn't segfault at runtime but the following one does:
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", mysql_errno(m), mysql_error(m));

Both snippets produce the same output though. Is this mis-use of printf() in
the last snippet or a mysql c api problem (if so, I will ask this question
elsewhere)?

Thanks for any help

/ Eric
Nov 14 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a

"Eric Lilja" <er*************@yahoo.com> wrote in message
news:cr**********@news.island.liu.se...
Hello, I have two code snippets I want you to look at. My program compiles
without warnings (warning level set to max, gcc 3.4.3) with either snippet
but the latter one causes a segfault at run-time. I know it contains
non-standard constructs (using the MySql C api) but I wanted to know if it's printf() I'm misuing. Here are the snippets:

/* m is of type MYSQL* */
unsigned int code = mysql_errno(m);
const char *description = mysql_error(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", code, description);
}

This snippet doesn't segfault at runtime but the following one does:
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", mysql_errno(m), mysql_error(m));

Both snippets produce the same output though. Is this mis-use of printf() in the last snippet or a mysql c api problem (if so, I will ask this question
elsewhere)?


The proper 'printf()' specifier for type 'unsigned int'
is %u. For type 'char *' (or 'const char*') it's %s.
If your supplied arguments' types do not match the
specifiers, the behavior is undefined, in which case
*anything* could happen, from 'segfault' to 'seems to work'
or anything else.

-Mike
Nov 14 '05 #2

P: n/a

"Mike Wahler"wrote:

"Eric Lilja" <er*************@yahoo.com> wrote in message
news:cr**********@news.island.liu.se...
Hello, I have two code snippets I want you to look at. My program
compiles
without warnings (warning level set to max, gcc 3.4.3) with either
snippet
but the latter one causes a segfault at run-time. I know it contains
non-standard constructs (using the MySql C api) but I wanted to know if it's
printf() I'm misuing. Here are the snippets:

/* m is of type MYSQL* */
unsigned int code = mysql_errno(m);
const char *description = mysql_error(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", code, description);
}

This snippet doesn't segfault at runtime but the following one does:
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", mysql_errno(m), mysql_error(m));

Both snippets produce the same output though. Is this mis-use of printf()

in
the last snippet or a mysql c api problem (if so, I will ask this
question
elsewhere)?


The proper 'printf()' specifier for type 'unsigned int'
is %u. For type 'char *' (or 'const char*') it's %s.
If your supplied arguments' types do not match the
specifiers, the behavior is undefined, in which case
*anything* could happen, from 'segfault' to 'seems to work'
or anything else.


Thanks for catching that error, Mike. Unfortunately, my problem remains so I
can only assume I've encountered a problem with the mysql c api code. I will
look for an appropriate forum and ask there.
-Mike


/ Eric
Nov 14 '05 #3

P: n/a

"Eric Lilja" <er*************@yahoo.com> wrote in message
news:cr*********@news.island.liu.se...

"Mike Wahler"wrote:

"Eric Lilja" <er*************@yahoo.com> wrote in message
news:cr**********@news.island.liu.se...
Hello, I have two code snippets I want you to look at. My program
compiles
without warnings (warning level set to max, gcc 3.4.3) with either
snippet
but the latter one causes a segfault at run-time. I know it contains
non-standard constructs (using the MySql C api) but I wanted to know if it's
printf() I'm misuing. Here are the snippets:

/* m is of type MYSQL* */
unsigned int code = mysql_errno(m);
const char *description = mysql_error(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", code, description);
}

This snippet doesn't segfault at runtime but the following one does:
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", mysql_errno(m), mysql_error(m));

Both snippets produce the same output though. Is this mis-use of
printf() in
the last snippet or a mysql c api problem (if so, I will ask this
question
elsewhere)?


The proper 'printf()' specifier for type 'unsigned int'
is %u. For type 'char *' (or 'const char*') it's %s.
If your supplied arguments' types do not match the
specifiers, the behavior is undefined, in which case
*anything* could happen, from 'segfault' to 'seems to work'
or anything else.


Thanks for catching that error, Mike. Unfortunately, my problem remains so

I can only assume I've encountered a problem with the mysql c api code. I will look for an appropriate forum and ask there.


You can find out if the 'mysql' stuff is the problem by
removing it from your program and substituting 'dummy'
variables to represent e.g. mysql function return values,
and give those to 'printf()'. Also, note that often a
bug can easily wait to manifest itself until execution
reaches some part of the code other than where the bug
actually is. I.e. 'divide and conquer'. Do your program
in small pieces. Perform unit tests.

-Mike
Nov 14 '05 #4

P: n/a
In article <cr**********@news.island.liu.se>,
"Eric Lilja" <er*************@yahoo.com> wrote:
Hello, I have two code snippets I want you to look at. My program compiles
without warnings (warning level set to max, gcc 3.4.3) with either snippet
but the latter one causes a segfault at run-time. I know it contains
non-standard constructs (using the MySql C api) but I wanted to know if it's
printf() I'm misuing. Here are the snippets:

/* m is of type MYSQL* */
unsigned int code = mysql_errno(m);
const char *description = mysql_error(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", code, description);
}

This snippet doesn't segfault at runtime but the following one does:
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", mysql_errno(m), mysql_error(m));

Both snippets produce the same output though. Is this mis-use of printf() in
the last snippet or a mysql c api problem (if so, I will ask this question
elsewhere)?
1. In the second code it is not defined in which order mysql_errno and
mysql_error are called. There might be a dependency; maybe mysql_error
returns NULL until after a call to mysql_errno which returns a non-zero
value. Try what happens if you start with
const char *description = mysql_error(m);
unsigned int code = mysql_errno(m);


that is in reverse order.

2. Obviously if mysql_errno returns zero then the output will be
different. Quite possible that mysql_error will then return NULL, which
means the first printf isn't called at all while the second one crashes.

3. Or do you mean you called mysql_errno and mysql_error once before the
printf and then again within the printf? Maybe mysql_errno reports an
error only once (any errors since the previous call to mysql_errno? ),
so the printf will crash.
Nov 14 '05 #5

P: n/a

"Christian Bau" wrote:
In article <cr**********@news.island.liu.se>,
"Eric Lilja" <er*************@yahoo.com> wrote:
Hello, I have two code snippets I want you to look at. My program
compiles
without warnings (warning level set to max, gcc 3.4.3) with either
snippet
but the latter one causes a segfault at run-time. I know it contains
non-standard constructs (using the MySql C api) but I wanted to know if
it's
printf() I'm misuing. Here are the snippets:

/* m is of type MYSQL* */
unsigned int code = mysql_errno(m);
const char *description = mysql_error(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", code, description);
}

This snippet doesn't segfault at runtime but the following one does:
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", mysql_errno(m), mysql_error(m));

Both snippets produce the same output though. Is this mis-use of printf()
in
the last snippet or a mysql c api problem (if so, I will ask this
question
elsewhere)?
1. In the second code it is not defined in which order mysql_errno and
mysql_error are called. There might be a dependency; maybe mysql_error
returns NULL until after a call to mysql_errno which returns a non-zero
value. Try what happens if you start with
const char *description = mysql_error(m);
unsigned int code = mysql_errno(m);


that is in reverse order.


Very interesting. I tried switching the order and it did indeed alter the
programs behaviour. It didn't cause a crash, but different output.

unsigned int code = mysql_errno(m);
const char *description = mysql_error(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %u\n"
"Description: %s\n", code, description);
}

yields the output:
Failed to create chemistry recipe table.
Error code: 1050
Description: Table 'chemistry_recipes' already exists

and with the initilizations switched:
const char *description = mysql_error(m);
unsigned int code = mysql_errno(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %u\n"
"Description: %s\n", code, description);
}
yields this output:
Failed to create chemistry recipe table.
Error code: 10373019
Description: Table 'chemistry_recipes' already exists
(note the different error code)

2. Obviously if mysql_errno returns zero then the output will be
different. Quite possible that mysql_error will then return NULL, which
means the first printf isn't called at all while the second one crashes.

3. Or do you mean you called mysql_errno and mysql_error once before the
printf and then again within the printf? Maybe mysql_errno reports an
error only once (any errors since the previous call to mysql_errno? ),
so the printf will crash.


/ Eric
Nov 14 '05 #6

P: n/a
Eric Lilja wrote:
Hello, I have two code snippets I want you to look at. My program compiles
without warnings (warning level set to max, gcc 3.4.3) with either snippet
but the latter one causes a segfault at run-time. I know it contains
non-standard constructs (using the MySql C api) but I wanted to know if it's
printf() I'm misuing. Here are the snippets:

/* m is of type MYSQL* */
unsigned int code = mysql_errno(m);
const char *description = mysql_error(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", code, description);
}

This snippet doesn't segfault at runtime but the following one does:
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", mysql_errno(m), mysql_error(m));

Both snippets produce the same output though.
That I don't understand. If they produce the same output, then the
segfault is probably occurring *after* this line. It is very unlikely
that a line of code will both cause a segfault and be executed with
otherwise expected results.
Is this mis-use of printf() in
the last snippet or a mysql c api problem (if so, I will ask this question
elsewhere)?

The first snippet checks to see if description is NULL; the second does
not check that mysql_error(m) is NULL. There are, then, two probable
scenarios
1) Most likely: The segfault does not occur where you think it does.
2) Less likely: mysql_error(m) is not 0 in the first snippet at the
point that its value is assigned to description, but is 0 in the second
snippet at the point that it is returned to printf.

Nov 14 '05 #7

P: n/a
"Eric Lilja" <er*************@yahoo.com> writes:
Hello, I have two code snippets I want you to look at. My program compiles
without warnings (warning level set to max, gcc 3.4.3) with either snippet
but the latter one causes a segfault at run-time. I know it contains
non-standard constructs (using the MySql C api) but I wanted to know if it's
printf() I'm misuing. Here are the snippets:

/* m is of type MYSQL* */
unsigned int code = mysql_errno(m);
const char *description = mysql_error(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", code, description);
}

This snippet doesn't segfault at runtime but the following one does:
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", mysql_errno(m), mysql_error(m));

Both snippets produce the same output though. Is this mis-use of printf() in
the last snippet or a mysql c api problem (if so, I will ask this question
elsewhere)?


Use "%u", not "%d" to print an unsigned int (but this isn't going to
cause a seg fault).

What are the declared return types of mysql_errno and mysql_error?
Did you include the header that declares them?

And as someone else mentioned, there may be an ordering dependency on
the calls to mysql_errno() and mysql_error() in your second printf().

--
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.
Nov 14 '05 #8

P: n/a
Keith Thompson wrote:
"Eric Lilja" <er*************@yahoo.com> writes:
Hello, I have two code snippets I want you to look at. My program
compiles without warnings (warning level set to max, gcc 3.4.3)
with either snippet but the latter one causes a segfault at
run-time. I know it contains non-standard constructs (using the
MySql C api) but I wanted to know if it's printf() I'm misuing.
Here are the snippets:

/* m is of type MYSQL* */
unsigned int code = mysql_errno(m);
const char *description = mysql_error(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", code, description);
}

This snippet doesn't segfault at runtime but the following one
does:

printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", mysql_errno(m), mysql_error(m));

Both snippets produce the same output though. Is this mis-use of
printf() in the last snippet or a mysql c api problem (if so, I
will ask this question elsewhere)?


Use "%u", not "%d" to print an unsigned int (but this isn't going
to cause a seg fault).

What are the declared return types of mysql_errno and mysql_error?
Did you include the header that declares them?

And as someone else mentioned, there may be an ordering dependency on
the calls to mysql_errno() and mysql_error() in your second printf().


The first is guarded against 0/NULL values for code/description,
while the second has no such guard to the corresponding printf
arguments. I suspect printf itself is aborting on finding a NULL
to satisfy a %s specification.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #9

P: n/a
Eric Lilja wrote:
[...]
/* m is of type MYSQL* */
unsigned int code = mysql_errno(m);
const char *description = mysql_error(m);

if(code && description)
{
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", code, description);
}

This snippet doesn't segfault at runtime but the following one does:
printf("Failed to create chemistry recipe table.\n"
"Error code: %d\n"
"Description: %s\n", mysql_errno(m), mysql_error(m));

Both snippets produce the same output though. Is this mis-use of printf() in
the last snippet or a mysql c api problem (if so, I will ask this question
elsewhere)?

[...]

I would suggest against using the latter approach. The calling
conventions being used determine the order in which the arguments are
passed. I would generally avoid calling multiple functions or using
prefix/postfix expressions within argument lists.

Regards,
Jonathan.
Nov 14 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.