gcc initialization better or extra line of execution

B

Ben Bacarisse

Seebs said:
I am sort of curious, now. I know that gcc is smart enough to optimize:
printf("%s\n", foo);
to:
puts(foo);

But let's say you have a slightly longer example:
printf("%s", "hello\n");

Will any compilers optimize this to
puts("hello");
?

Yes, gcc 4.8.1 does, even with -O0 (just an example, other versions may
also do so).
 
F

Fred K

Seebs <[email protected]> writes: <snip> > I am sort of curious, now. I know that gcc is smart enough to optimize: > printf("%s\n", foo); > to: > puts(foo); > > But let's say you have a slightly longer example: > printf("%s", "hello\n"); > > Will any compilers optimize this to > puts("hello"); > ? Yes, gcc 4.8.1 does, even with -O0 (just an example, other versions may also do so). -- Ben.


Why not dispense with the strcpy or memcpy and just write:

char arr[128] = "testing";
 
B

Ben Bacarisse

Fred K said:
Why not dispense with the strcpy or memcpy and just write:

char arr[128] = "testing";

Read the whole thread and you'll see that the initial information was
incorrect. The above is not an option, as it turns out.
 
M

Malcolm McLean

Ok, first of all, I'm going to assume that in a real-world application,
your input string would be some passed-in argument and just "testing".


Thus:

I would reject this out of hand because you're not confirming
that the input string fits in the array. That alone makes the code
completely unacceptable. If you wrote this on a white board
during an interview, you would not get the job.
Though you've got the issue of what to do if passed an over-long string.
Are wrong results better or worse than no results? That is should you
truncate the string, or terminate the program? It's hard to know if
you're writing a subroutine and you don't know the context in which it will
be called.
You could use dynamic allocation, but that could easily prolong the misery
if every sensible string is short, and it will slow down the program. Then
the out of memory condition still has to be handled somewhere.
The normal solution is just to pass an error flag back up to caller. But
that makes code hard to read. caller looks like this

if( payemployee("Fred Bloggs") < 0)
{
fprintf(stderr, "Fred Blogg's name too long for internal buffer");
return -1; /* give the problem to someone else */

}

all for a condition which can never happen.
 
B

BruceS

glen herrmannsfeldt said:
Finally, I offer:

Progarm 'F'
main()
{
char array[128];
strncpy(array, "testing", sizeof(a));
}

How is the strncpy call better than

strcpy(array, "testing");

? Using strncpy rather than strcpy gives no added safety *in this case*
because it's obvious that the array is more than big enough. And if it
weren't obvious, you'd risk leaving the target array unterminated (i.e.,
not containing a string). Furthermore, since we're talking about speed,
strncpy() is likely to be very slightly more expensive than an
equivalent strcpy(), since (a) it has to check against both the length
and the null terminator in the source, and (b) it (probably
unnecessarily) pads the target with nulls.

[...]

Perhaps I'm missing something, but I would think a better question would
be "What is sizeof(a)?" I can only assume that should have been "sizeof
array", but maybe there's something else going on that I didn't get.
 
F

Fred K

Fred K <[email protected]> writes: <snip> > Why not dispense with the strcpy or memcpy and just write: > > char arr[128] = "testing"; Read the whole thread and you'll see that the initial information was incorrect. The above is not an option, as it turns out. -- Ben.

True, it is not one of the two options the OP mentioned.

But the implication of "which is the better program", and smaller code sizeand/or shorter execution time shows that whoever wrote the request (eitherthe OP or possibly his teacher) should have considered all options.

If an interviewer asked me "Which is better, A or B", I would never hesitate to say "neither - C is obviously better" if that is what I believed. And in this case, the miniscule difference in speed or size should be overridden by thoughts of the future maintainability of the code.
 
S

Seebs

Yes, gcc 4.8.1 does, even with -O0 (just an example, other versions may
also do so).

Interesting! I wasn't sure whether it was a special case for "%s\n", or
whether they were also examining the contents of the string literal.

-s
 
B

Ben Bacarisse

Fred K said:
dispense with the strcpy or memcpy and just write: > > char arr[128]
= "testing"; Read the whole thread and you'll see that the initial
information was incorrect. The above is not an option, as it turns
out. -- Ben.

Your client is messing up the quoting.
True, it is not one of the two options the OP mentioned.

Nor one of the ones I thought possible. Some people (well, me at least)
never thought that the question was about the code posted -- the
examples were so obviously a fragment, that the question became one of
guessing was what element was really being asked about. I decided it
was the copy operation, not how to initialise an array. Others took a
different view, and your suggestion has, I think, been made more than
once in the thread.

<snip>
 
S

Stephen Sprunk

Interesting! I wasn't sure whether it was a special case for "%s\n",
or whether they were also examining the contents of the string
literal.

A little bit of Googling found me this:

"
This printf to puts/putchar optimization is done in the source file
gcc/builtins.c in the GCC source tree. In this source file, look at the
fold_builtin_printf function. The rules to determine which optimization
to perform are as follows (note the order of rules it checks is important):

1. Return value is used: No optimization.
2. The format string is not a literal constant: No optimization.
3. The format string has no % in it:
1. The format string has length 0: Eliminate this printf call.
2. The format string has length 1: Call putchar
3. The format string is of form "string\n": Create a NULL-terminated
string that's one char shorter than the original, and call puts. (This
is our C code example above)
4. Otherwise, no optimization.
4. The format string is of form "%s\n": Call puts.
5. The format string is of form "%c": Call putchar.
6. Otherwise, no optimization.
"

Seems pretty logical.

Note: the above applies even at -O0; the GCC folks apparently don't
think that built-in functions are an "optimization".

S
 
S

Seebs

"
This printf to puts/putchar optimization is done in the source file
gcc/builtins.c in the GCC source tree. In this source file, look at the
fold_builtin_printf function. The rules to determine which optimization
to perform are as follows (note the order of rules it checks is important):

1. Return value is used: No optimization.
2. The format string is not a literal constant: No optimization.
3. The format string has no % in it:
1. The format string has length 0: Eliminate this printf call.
2. The format string has length 1: Call putchar
3. The format string is of form "string\n": Create a NULL-terminated
string that's one char shorter than the original, and call puts. (This
is our C code example above)
4. Otherwise, no optimization.
4. The format string is of form "%s\n": Call puts.
5. The format string is of form "%c": Call putchar.
6. Otherwise, no optimization.
"

Seems pretty logical.

It does, but it doesn't seem to me that this should produce the second
optimization I described, because "%s" is not any of the above. All I have
handy is clang/llvm, and it doesn't convert printf("%s", "hello\n") to
puts("hello").

-s
 
S

Stephen Sprunk

It does, but it doesn't seem to me that this should produce the
second optimization I described, because "%s" is not any of the
above. All I have handy is clang/llvm, and it doesn't convert
printf("%s", "hello\n") to puts("hello").

I suspect that a related optimization that converts printf("%s",
"hello\n") to printf("hello\n"), which then falls under the above.
Perhaps this is a rather aggressive form of inlining?

The (ancient) GCC on my sandbox doesn't do this, so I can't experiment
with how clever the optimizations have gotten or what their limits are.
If you're interested, though, the quote above says where you can find
the implementation details.

S
 
K

Ken Brody

Yes, we all get that a decent compiler would optimize the whole
thing away. Consider it to be a code fragment and not a complete
program.

Given that the OP asked for specifics, such as platform, disassembly, CPU
cycles, and code size, the answer must be given in terms of the actual
posted code, and not some assumptions as to what the code in a "complete
program" would look like.
 
S

Seebs

In that case, thank you Keith for unravelling my apparent
unintended obfuscation.

I think in this case what you said was relatively clear, but I had an
excess of blood in my caffeine stream.

-s
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top