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

why use fprintf / size_t instead of printf/ int

P: n/a

E. Robert Tisdale wrote:

int main(int argc, char* argv[]) {
quad_t m = {0, 1, 2, 3};
int r;
fprintf(stdout, "m = (");
for (size_t j = 0; j < 4; ++j)
Why did you declare j as type size_t ?
fprintf(stdout, " %d", m[j]);
fprintf(stdout, ")\n");
WHy did you use fprintf here?
w0(&r, m);
fprintf(stdout, "r = %d\n", r);
return 0;


I'm only asking because I'm one of those people who started out using
functions like gets, strcat, atol and strcpy before being adviced to
use alternatives (fgets, strncat, strtol, and strncpy). Maybe you call
tell me what type of "potential" bug you are trying to prevent by using
fprintf and size_t.

Thanks

Gaya

Nov 14 '05 #1
Share this Question
Share on Google+
17 Replies


P: n/a
G Patel wrote:
E. Robert Tisdale wrote:
int main(int argc, char* argv[]) {
quad_t m = {0, 1, 2, 3};
int r;
fprintf(stdout, "m = (");
for (size_t j = 0; j < 4; ++j)


Why did you declare j as type size_t?
fprintf(stdout, " %d", m[j]);
fprintf(stdout, ")\n");


WHy did you use fprintf here?
w0(&r, m);
fprintf(stdout, "r = %d\n", r);
return 0;


I'm only asking because
I'm one of those people who started out using functions
like gets, strcat, atol and strcpy before being advized
to use alternatives (fgets, strncat, strtol, and strncpy).
Maybe you call tell me what type of "potential" bug
you are trying to prevent by using fprintf and size_t.


Don't look for profound reasoning here.
It's mostly a matter of style.
I use size_t for subscript j and extent n because

0<= j < n

in the declaration of array

int m[n];

I should have written something like:

FILE* myout = stdout;
fprintf(myout, "m = (");
for (size_t j = 0; j < 4; ++j)
fprintf(myout, " %d", m[j]);
fprintf(myout, ")\n");

but I was lazy and
I didn't want to distract attention from the problem at hand.
But this is convenient if, later, I decide that
I really need to redirect this output to a log file for example.
Nov 14 '05 #2

P: n/a
On 25 Jan 2005 19:10:03 -0800, "G Patel" <ga********@gmail.com> wrote
in comp.lang.c:

E. Robert Tisdale wrote:

int main(int argc, char* argv[]) {
quad_t m = {0, 1, 2, 3};
int r;
fprintf(stdout, "m = (");
for (size_t j = 0; j < 4; ++j)
Why did you declare j as type size_t ?


Tisdale is a troll and an idiot. There is absolutely no reason at all
to prefer size_t to int in this situation.
fprintf(stdout, " %d", m[j]);
fprintf(stdout, ")\n");


WHy did you use fprintf here?


Tisdale is still a troll and an idiot. There is absolutely no reason
to prefer fprintf(stdout, /* whatever */) to printf(/* whatever */)
here, or under any circumstances that I can think of off-hand.
Although if there is a case where there is a difference, someone here
will correct me.

There are times when it can be considered reasonable to use
fputs(text_string, stdout) over puts(text_string), when you do not,
for some reason, want a '\n' appended and you are otherwise not using
printf().
w0(&r, m);
fprintf(stdout, "r = %d\n", r);
return 0;


I'm only asking because I'm one of those people who started out using
functions like gets, strcat, atol and strcpy before being adviced to
use alternatives (fgets, strncat, strtol, and strncpy). Maybe you call
tell me what type of "potential" bug you are trying to prevent by using
fprintf and size_t.

Thanks


There is nothing wrong with asking the question, if you don't know the
relative reliability of the posters. The best piece of advice you
advice you can gather from this particular exchange is to ignore
Tisdale. Period.

Personally, I have him kill filed, and only see such of his posts as
people like you quote in replies.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #3

P: n/a
G Patel wrote:

E. Robert Tisdale wrote:

int main(int argc, char* argv[]) {
quad_t m = {0, 1, 2, 3};
int r;
fprintf(stdout, "m = (");
for (size_t j = 0; j < 4; ++j)


Why did you declare j as type size_t ?
fprintf(stdout, " %d", m[j]);
fprintf(stdout, ")\n");


WHy did you use fprintf here?
w0(&r, m);
fprintf(stdout, "r = %d\n", r);
return 0;


I'm only asking because I'm one of those people who started out using
functions like gets, strcat, atol and strcpy before being adviced to
use alternatives (fgets, strncat, strtol, and strncpy). Maybe you call
tell me what type of "potential" bug you are trying to prevent by using
fprintf and size_t.


Tisdale has a lot of strange coding practices. The above is not
wrong, but is definitely not preferable standard C coding
practices.

My suggestion is that you ignore him. At his best he's just a fool,
but its not uncommon for him to be plain wrong.

Erik
--
+-----------------------------------------------------------+
Erik de Castro Lopo no****@mega-nerd.com (Yes it's valid)
+-----------------------------------------------------------+
Being really good at C++ is like being really good at using rocks to
sharpen sticks." -- Thant Tessman
Nov 14 '05 #4

P: n/a
Jack Klein wrote:
Why did you declare j as type size_t ?


Tisdale is a troll and an idiot. There is absolutely no reason at all
to prefer size_t to int in this situation.
fprintf(stdout, " %d", m[j]);


size_t is the first type that comes to my mind
when I consider which type to use for an array index.

--
pete
Nov 14 '05 #5

P: n/a
pete wrote:
Jack Klein wrote:
Why did you declare j as type size_t ?


Tisdale is a troll and an idiot. There is absolutely no reason
at all to prefer size_t to int in this situation.
fprintf(stdout, " %d", m[j]);


size_t is the first type that comes to my mind
when I consider which type to use for an array index.


OK, you have rebutted Jacks last assertion. Are you also cavilling
about his other assertions? Also consider that a size_t MAY
require more storage space and processing than an int.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson

Nov 14 '05 #6

P: n/a
in comp.lang.c i read:
I'm only asking because I'm one of those people who started out using
functions like gets, strcat, atol and strcpy before being adviced to
use alternatives (fgets, strncat, strtol, and strncpy).


as an aside: i hope someone explained how unsafe strncpy can be, and thus
how to use it semi-safely.

--
a signature
Nov 14 '05 #7

P: n/a
CBFalconer wrote:

pete wrote:
Jack Klein wrote:
Why did you declare j as type size_t ?

Tisdale is a troll and an idiot. There is absolutely no reason
at all to prefer size_t to int in this situation.

> fprintf(stdout, " %d", m[j]);
size_t is the first type that comes to my mind
when I consider which type to use for an array index.


OK, you have rebutted Jacks last assertion. Are you also cavilling
about his other assertions?


No, but I want to get off that bandwagon as soon as possible.
Also consider that a size_t MAY
require more storage space and processing than an int.


int is not my first choice to default to
for selecting the type of an array index.
I prefer size_t and my second choice is unsigned.

I know that size_t has the range to index into any array.
I also consider that array index values
are likely to be derived from or compared to
expressions like (sizeof array / sizeof *array)
or expressions involving strlen, which have size_t types.

As far as any speed concerns go, I think that this
particular premature optimization of assuming that size_t
is significantly slower than int, is very premature.
Not worth consider without knowing the performance requirments
and the implementation.

My philosphy on saving memory by using small types
is that it mostly only makes sense for large arrays of small types.
Otherwise a situation, where the difference
between declaring a variable of type long
and declaring a variable of type int,
makes a real difference in the amount of available memory,
would be a very special situation indeed.
In such a situation, I think it would be worth investigating
whether further memory could be saved by using a char type instead.

If I had a special reason to use something instead of size_t
for an array index, then I would. For example, if I wanted
to print out the index values in C89 without using a cast.
But then, I would would still prefer unsigned over int,
to avoid any signed/unsigned mismatch problems from comparison and
assignment operations with sizeof and strlen expressions.

--
pete
Nov 14 '05 #8

P: n/a
those who know me have no need of my name <no****************@usa.net> writes:
as an aside: i hope someone explained how unsafe strncpy can be, and thus
how to use it semi-safely.


Here's my strncpy() boilerplate:

There is occasionally a good reason to use strncpy(). However:

* Using strncpy() into a large buffer can be very inefficient.
strncpy() always writes to every byte in the destination
buffer, which can waste a lot of time if the destination
buffer is much longer than the source string.

* If the source string is longer than the size of the
destination buffer, then strncpy() doesn't write a
terminating null. So a call to strncpy() must be followed
by explicitly writing a null terminator at the end of the
destination buffer in most cases.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Nov 14 '05 #9

P: n/a
pete wrote:
.... snip ...
I know that size_t has the range to index into any array.
I also consider that array index values
are likely to be derived from or compared to
expressions like (sizeof array / sizeof *array)
or expressions involving strlen, which have size_t types.

As far as any speed concerns go, I think that this
particular premature optimization of assuming that size_t
is significantly slower than int, is very premature.
Not worth consider without knowing the performance requirments
and the implementation.


Of course the proper way is to specify the range required for the
index variable, and let the compiler use that to select the optimal
storage. Pascal does this. In C we only have the option of
selecting something that is big enough. However, surely when we
write:

for (i = 0; i < 4; i++) ....

we have a good idea that i should never have values outside of
1..3, and knowing that int can cover this range, and is the most
efficiently handled integral type, we should have very few qualms
about selecting it as the index type.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #10

P: n/a
On Wed, 26 Jan 2005 08:28:55 GMT, pete <pf*****@mindspring.com> wrote
in comp.lang.c:
Jack Klein wrote:
Why did you declare j as type size_t ?
Tisdale is a troll and an idiot. There is absolutely no reason at all
to prefer size_t to int in this situation.

> fprintf(stdout, " %d", m[j]);


size_t is the first type that comes to my mind
when I consider which type to use for an array index.


It well may be the first type that comes to your mind. I can't
dispute that, I have no experience with your mind.

But in Trollsdale's original code, which you conveniently snipped and
I am putting back:
int main(int argc, char* argv[]) {
quad_t m = {0, 1, 2, 3};
int r;
fprintf(stdout, "m = (");
for (size_t j = 0; j < 4; ++j)
fprintf(stdout, " %d", m[j]);
fprintf(stdout, ")\n");
w0(&r, m);
fprintf(stdout, "r = %d\n", r);
return 0;


....given an array of 4 elements, and a for loop written with constants
to run between 0 and 3 inclusive, can you give any reason to disagree
with my statement:

"There is absolutely no reason at all to prefer size_t to int in this
situation."

Note that I did not say it was "bad" or "unwise" to use a size_t, nor
even any particular reason to prefer int over size_t.

Other than your personal preference, which does not count. Can you
make any statement, backed up by a reference to the C standard, that
use of a size_t to iterate from 0 to 3 is "better", "faster", "safer"
or "more robust" than using an int to iterate from 0 to 3?

In actual fact, there are reasons why it can be a disadvantage to use
a size_t over a signed type, such as int or ptrdif_t, if you are going
to do arithmetic on array indices and you might end up subtracting a
higher index from a lower one. If you are using size_t or any
unsigned type, you get the defined behavior of unsigned types on
mathematical underflow, and wind up with a very large positive value
almost certainly outside the bounds of your array.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #11

P: n/a
in comp.lang.c i read:
those who know me have no need of my name <no****************@usa.net> writes:

as an aside: i hope someone explained how unsafe strncpy can be, and thus
how to use it semi-safely.


Here's my strncpy() boilerplate:


excellent!

[btw: sorry about the misspelling on the wiki.]

--
a signature
Nov 14 '05 #12

P: n/a
Jack Klein wrote:
E. Robert Tisdale wrote:
int main(int argc, char* argv[]) {
quad_t m = {0, 1, 2, 3};
int r;
fprintf(stdout, "m = (");
for (size_t j = 0; j < 4; ++j)
fprintf(stdout, " %d", m[j]);
fprintf(stdout, ")\n");
w0(&r, m);
fprintf(stdout, "r = %d\n", r);
return 0;

...given an array of 4 elements, and a for loop written with constants
to run between 0 and 3 inclusive, can you give any reason to disagree
with my statement:

"There is absolutely no reason at all to prefer size_t to int in this
situation."

Note that I did not say it was "bad" or "unwise" to use a size_t, nor
even any particular reason to prefer int over size_t.

Other than your personal preference, which does not count. Can you
make any statement, backed up by a reference to the C standard, that
use of a size_t to iterate from 0 to 3 is "better", "faster", "safer"
or "more robust" than using an int to iterate from 0 to 3?

In actual fact, there are reasons why it can be a disadvantage to use
a size_t over a signed type, such as int or ptrdif_t, if you are going
to do arithmetic on array indices and you might end up subtracting a
higher index from a lower one. If you are using size_t or any
unsigned type, you get the defined behavior of unsigned types on
mathematical underflow, and wind up with a very large positive value
almost certainly outside the bounds of your array.


I don't think that it makes much sense to consider all of these options
or to compel other C programmers who must read, understand and maintain
my code to consider all of these options.
I use size_t for an array subscript because I know that
it is *always* a suitable type for an array subscript.
I don't need to worry about whether an int is negative
or adequate to index all of the elements of the array.
If an int or a float or a double or anything besides a size_t
appears in an array subscript, I am immediately suspicious
and I feel obliged to take extra time to study it and convince myself
that it actually references a valid element of the array.

But, as I pointed out in my original reply to Gaya Patel,
this is merely a matter of style.
My style helps me to spot bugs in my code
and I try to be consistent so that
other programmers can spot bugs in my code as well.
Nov 14 '05 #13

P: n/a
Jack Klein wrote:

On Wed, 26 Jan 2005 08:28:55 GMT, pete <pf*****@mindspring.com> wrote
in comp.lang.c:
Jack Klein wrote:
> Why did you declare j as type size_t ?

Tisdale is a troll and an idiot. There is absolutely no reason at all
to prefer size_t to int in this situation.

>
> > fprintf(stdout, " %d", m[j]);
size_t is the first type that comes to my mind
when I consider which type to use for an array index.


It well may be the first type that comes to your mind. I can't
dispute that, I have no experience with your mind.

But in Trollsdale's original code, which you conveniently snipped and
I am putting back:
int main(int argc, char* argv[]) {
quad_t m = {0, 1, 2, 3};
int r;
fprintf(stdout, "m = (");
for (size_t j = 0; j < 4; ++j)
fprintf(stdout, " %d", m[j]);
fprintf(stdout, ")\n");
w0(&r, m);
fprintf(stdout, "r = %d\n", r);
return 0;


...given an array of 4 elements, and a for loop written with constants
to run between 0 and 3 inclusive, can you give any reason to disagree
with my statement:

"There is absolutely no reason at all to prefer size_t to int in this
situation."

Note that I did not say it was "bad" or "unwise" to use a size_t, nor
even any particular reason to prefer int over size_t.

Other than your personal preference, which does not count. Can you
make any statement, backed up by a reference to the C standard, that
use of a size_t to iterate from 0 to 3 is "better", "faster", "safer"
or "more robust" than using an int to iterate from 0 to 3?


"more robust" means that it can interact better with code
that you haven't seen yet, so, yes I would say "more robust",
based on what I said about array indexes frequently
being related to sizeof derived expressions.
In actual fact, there are reasons why it can be a disadvantage to use
a size_t over a signed type, such as int or ptrdif_t, if you are going
to do arithmetic on array indices and you might end up subtracting a
higher index from a lower one.
I thought about that, but I've never seen any code like that.
If you are using size_t or any
unsigned type, you get the defined behavior of unsigned types on
mathematical underflow, and wind up with a very large positive value
almost certainly outside the bounds of your array.


--
pete
Nov 14 '05 #14

P: n/a
Jack Klein <ja*******@spamcop.net> wrote:
On Wed, 26 Jan 2005 08:28:55 GMT, pete <pf*****@mindspring.com> wrote
size_t is the first type that comes to my mind
when I consider which type to use for an array index.


I'm not taking anybody's sides in the discussion, but I have
similar bias as pete.

[snip] "There is absolutely no reason at all to prefer size_t to int in this
situation."
Yes.
I think there might be some reasons to prefer an unsigned type for
indexing arrays to a signed one, one of them might be to avoid warnings
such as:
t.c:6: warning: comparison between signed and unsigned
I think uniformity is more convenient here, and the choice has been
made by the library functions, which mostly operate on unsigned type
when dealing with buffers (or such is my impression).

If I were to index an array from its beginning (conceptually), then
I would choose an unsigned type; if I were to index it in the middle,
then I would choose signed.
In actual fact, there are reasons why it can be a disadvantage to use
a size_t over a signed type, such as int or ptrdif_t, if you are going
to do arithmetic on array indices and you might end up subtracting a
higher index from a lower one. If you are using size_t or any
unsigned type, you get the defined behavior of unsigned types on
mathematical underflow, and wind up with a very large positive value
almost certainly outside the bounds of your array.


IMHO it depends. If this arithmetic is intentional, then you must use
(or cast to) signed type. If you mean an error, then it's definitely
better to land safely somewhere at the end of virtual memory (supposing
the result is used further to access this or some other array) and get
a friendly core dump, rather than silently overwrite whatever happens
to be before the array.

--
Stan Tobias
mailx `echo si***@FamOuS.BedBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Nov 14 '05 #15

P: n/a
There might be one reason to use size_t, but this is just a guess. I
hope someone can confirm or deny this:

When the code is compiled, the computer needs to find the memory
address for the array start and add the according offset of the array
index. I believe that the base address is of type size_t, so if we use
int as array index we need to convert it to size_t before
addition. This is probably only one machine instruction and as such
mostly a theoretic consideration.

So, where did I go wrong with my guesswork ?

Vesa
Nov 14 '05 #16

P: n/a
Vesa Siivola <vs******@DoNotSpamMe.cc.hut.fi> writes:
There might be one reason to use size_t, but this is just a guess. I
hope someone can confirm or deny this:
Use size_t for what? You didn't quote anything from the previous
article, and I can't find it on my news server (and you didn't even
post through google).
When the code is compiled, the computer needs to find the memory
address for the array start and add the according offset of the array
index. I believe that the base address is of type size_t, so if we use
int as array index we need to convert it to size_t before
addition. This is probably only one machine instruction and as such
mostly a theoretic consideration.

So, where did I go wrong with my guesswork ?


The base address is of a pointer type, not of type size_t. It's
likely to be the the same size as a size_t, but whether any conversion
is required, and how much (if anything) it costs, is system-specific.

There may be good reasons to use size_t rather than int as an array
index, but this kind of micro-optimization isn't one of them.

--
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 #17

P: n/a
Keith Thompson <ks***@mib.org> wrote:
: Use size_t for what? You didn't quote anything from the previous
: article, and I can't find it on my news server (and you didn't even
: post through google).

I could not find the original question either, just some flaming
follow-ups. I guess it was a bit pointless to even reply to such an
old message anyways. Good thing you guessed the original question
right.

: The base address is of a pointer type, not of type size_t. It's
: likely to be the the same size as a size_t, but whether any conversion
: is required, and how much (if anything) it costs, is system-specific.

You are right. Again, just guessing, its probably less likely that a
size_t should be converted than int. But this is just nitpicking.

: There may be good reasons to use size_t rather than int as an array
: index, but this kind of micro-optimization isn't one of them.
I agree.

Vesa
Nov 14 '05 #18

This discussion thread is closed

Replies have been disabled for this discussion.