Say i have a function:
char *rmtrail(char *str)
{
if (str)
{
int i;
for (i = strlen(str) - 1; i >= 0 && isspace(str[i]); --i)
;
str[++i] = '\0';
}
return str;
}
that removes trailing spaces from a string. The result of this
function will be different, if I change the return type from char* to
void and remove 'return str' ? I mean, in the caller function i call
rmtrail, passing a pointer to string. Even though in rmtrail, i
received a copy of the pointer to my string, the modified string will
be the same, so where's the need to return 'str' from rmtrail
function ? This function was not coded by me, but it works fine.
I just want to know if there is any difference... 15 2243
Liviu <ol****@gmail.comwrote:
Say i have a function:
char *rmtrail(char *str)
{
if (str)
{
int i;
for (i = strlen(str) - 1; i >= 0 && isspace(str[i]); --i)
;
str[++i] = '\0';
}
return str;
}
that removes trailing spaces from a string. The result of this
function will be different, if I change the return type from char* to
void and remove 'return str' ? I mean, in the caller function i call
rmtrail, passing a pointer to string. Even though in rmtrail, i
received a copy of the pointer to my string, the modified string will
be the same, so where's the need to return 'str' from rmtrail
function ? This function was not coded by me, but it works fine.
I just want to know if there is any difference...
The difference will be in the way you can call it, but functionally, it
will indeed remain the same. Compare this with, say, strcpy(); it, too,
returns a pointer to the string you just copied, which is the very same
pointer you passed in. That's the way you have it now. Both strcpy() and
your function could return nothing and remain functionally the same,
eliminating only some not very readable constructs such as
strcpy(rmtrail(strcat(rmtrail(......))));.
IMO, both functions would be improved if they returned a pointer, not to
the first, but to the last character of their results. That way, you
could at least use the result for slightly more efficient string
construction.
Richard
On Jun 27, 3:57 pm, r...@hoekstra-uitgeverij.nl (Richard Bos) wrote:
Liviu <oli...@gmail.comwrote:
Say i have afunction:
char *rmtrail(char *str)
{
if (str)
{
int i;
for (i = strlen(str) - 1; i >= 0 && isspace(str[i]); --i)
;
str[++i] = '\0';
}
returnstr;
}
that removes trailing spaces from a string. The result of this
functionwill be different, if I change thereturntype from char* to
void and remove 'returnstr' ? I mean, in the callerfunctioni call
rmtrail, passing apointerto string. Even though in rmtrail, i
received a copy of thepointerto my string, the modified string will
be the same, so where's the need toreturn'str' from rmtrail
function? Thisfunctionwas not coded by me, but it works fine.
I just want to know if there is any difference...
The difference will be in the way you can call it, but functionally, it
will indeed remain the same. Compare this with, say, strcpy(); it, too,
returns apointerto the string you just copied, which is the very samepointeryou passed in. That's the way you have it now. Both strcpy() and
yourfunctioncouldreturnnothing and remain functionally the same,
eliminating only some not very readable constructs such as
strcpy(rmtrail(strcat(rmtrail(......))));.
IMO, both functions would be improved if they returned apointer, not to
the first, but to the last character of their results. That way, you
could at least use the result for slightly more efficient string
construction.
Richard
I understand now. So, as long as i dont need the result of my function
'rmtrail' as a parameter to other function (making an not so readable
syntax) i can change the returned type (to void) without any bad
consequnces.
Thank you.
Liviu wrote:
>
Say i have a function:
char *rmtrail(char *str) {
if (str) {
int i;
for (i = strlen(str) - 1; i >= 0 && isspace(str[i]); --i) ;
str[++i] = '\0';
}
return str;
} /* edited for space, cbf */
As written that function is a usage trap. One is likely to write
something like:
printf("%s\n%s\n", str, rmtrail(str));
and expect to get two different strings. You won't. By making the
function return an error indicator, or a void, you avoid that trap.
--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net
--
Posted via a free Usenet account from http://www.teranews.com
Liviu <ol****@gmail.comwrites:
[...]
>Liviu <oli...@gmail.comwrote:
Say i have afunction:
char *rmtrail(char *str)
{
if (str)
{
int i;
for (i = strlen(str) - 1; i >= 0 && isspace(str[i]); --i)
;
str[++i] = '\0';
}
returnstr;
}
[...]
I understand now. So, as long as i dont need the result of my function
'rmtrail' as a parameter to other function (making an not so readable
syntax) i can change the returned type (to void) without any bad
consequnces.
Yes. Or you can leave the function as it is, and just ignore the
returned result if you don't happen to need it.
--
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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Liviu <oli...@gmail.comwrote:
Say i have afunction:
char *rmtrail(char *str)
{
if (str)
{
int i;
for (i = strlen(str) - 1; i >= 0 && isspace(str[i]); --i)
;
str[++i] = '\0';
}
returnstr;
}
This function invokes undefined behavior when called with a whitespace-only
string.
On Jun 27, 5:45 pm, CBFalconer <cbfalco...@yahoo.comwrote:
Liviu wrote:
Say i have a function:
char *rmtrail(char *str) {
if (str) {
int i;
for (i = strlen(str) - 1; i >= 0 && isspace(str[i]); --i) ;
str[++i] = '\0';
}
return str;
} /* edited for space, cbf */
As written that function is a usage trap. One is likely to write
something like:
printf("%s\n%s\n", str, rmtrail(str));
and expect to get two different strings. You won't. By making the
function return an error indicator, or a void, you avoid that trap.
It's true...I often use this construct in C#.
dykeinthebox wrote, On 27/06/07 17:13:
>>Liviu <oli...@gmail.comwrote: Say i have afunction: char *rmtrail(char *str) { if (str) { int i; for (i = strlen(str) - 1; i >= 0 && isspace(str[i]); --i) ; str[++i] = '\0'; } returnstr; }
This function invokes undefined behavior when called with a whitespace-only
string.
Where? The final loops will have..
--i; /* i is now 0 */
i >=0 /* true, so continue */
isspace(str[i]) /* true so continue */
--i; /* i is now -1 */
i >=0 /* false, so the sub-expression after && not executed and loop
ends */
str[++i] = '\0'; /* value of i+1 used, i.e. str[0] = '\0' */
The problems are, I think
1) with an empty string if SIZE_MAX>INT_MAX (often the case) as
(size_t)0 - 1 will give SIZE_MAX and I don't *think* you are guaranteed
that this will make i negative, although all I think it likely to work
with implementations I know
2) with strlen(str)>INT_MAX, where obviously it won't fit in i!
The following minimally changed version is safe.
char *rmtrail(char *str)
{
if (str && str[0]) {
size_t i;
for (i = strlen(str) - 1;
i != SIZE_MAX && isspace((unsigned char)str[i]); --i)
continue;
str[++i] = '\0';
}
return str;
}
Note the cast to unsigned char!
Personally I would probably do something more like:
char *rmtrail(char *str)
{
if (str && *str) {
size_t i = strlen(str);
while (--i && isspace((unsigned char)str[i]))
continue;
str[i+1] = '\0';
}
return str;
}
Or maybe
char *rmtrail(char *str)
{
if (str) {
char *end = str + strlen(str);
while (end>str && isspace((unsigned char)*--end))
continue;
*end = '\0';
}
return str;
}
Note that the above is all untested.
--
Flash Gordon
"CBFalconer" <cb********@yahoo.comha scritto nel messaggio news:46***************@yahoo.com...
Liviu wrote:
>> Say i have a function:
char *rmtrail(char *str) { if (str) { int i; for (i = strlen(str) - 1; i >= 0 && isspace(str[i]); --i) ; str[++i] = '\0'; } return str; } /* edited for space, cbf */
As written that function is a usage trap. One is likely to write
something like:
printf("%s\n%s\n", str, rmtrail(str));
and expect to get two different strings. You won't.
Why? There is a sequence point after each conversion specifier in
printf, so the first %s will print the old str.
In article <f6**********@tdi.cu.mi.it>, Army1987 <pl********@for.itwrote:
>There is a sequence point after each conversion specifier in printf
First time I've ever seen that claim. Citation, please?
--
All is vanity. -- Ecclesiastes
"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.caha scritto nel messaggio news:f6**********@canopus.cc.umanitoba.ca...
In article <f6**********@tdi.cu.mi.it>, Army1987 <pl********@for.itwrote:
>>There is a sequence point after each conversion specifier in printf
First time I've ever seen that claim. Citation, please?
7.19.1p1:
The formatted input/output functions shall behave as if there is a sequence point after the
actions associated with each specifier.
In article <f6**********@tdi.cu.mi.it>, Army1987 <pl********@for.itwrote:
>"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.caha scritto nel messaggio news:f6**********@canopus.cc.umanitoba.ca...
>In article <f6**********@tdi.cu.mi.it>, Army1987 <pl********@for.itwrote:
>>>There is a sequence point after each conversion specifier in printf
>First time I've ever seen that claim. Citation, please?
7.19.1p1: The formatted input/output functions shall behave as if there is a sequence point after the actions associated with each specifier.
Interesting. But is it applicable? The arguments to the formatted
I/O functions are evaluated before the function is called
(there is a sequence point after the evaluation of the parameters
but before the call), so if there are side effects in the parameters
they take place before you get around to the examination of the
conversion specifiers.
--
I was very young in those days, but I was also rather dim.
-- Christopher Priest
"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.caha scritto nel messaggio news:f6**********@canopus.cc.umanitoba.ca...
In article <f6**********@tdi.cu.mi.it>, Army1987 <pl********@for.itwrote:
>>"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.caha scritto nel messaggio news:f6**********@canopus.cc.umanitoba.ca...
>>In article <f6**********@tdi.cu.mi.it>, Army1987 <pl********@for.itwrote:
>>>>There is a sequence point after each conversion specifier in printf
>>First time I've ever seen that claim. Citation, please?
7.19.1p1: The formatted input/output functions shall behave as if there is a sequence point after the actions associated with each specifier.
Interesting. But is it applicable? The arguments to the formatted
I/O functions are evaluated before the function is called
(there is a sequence point after the evaluation of the parameters
but before the call), so if there are side effects in the parameters
they take place before you get around to the examination of the
conversion specifiers.
Yes. I realized that about one minute after I hit "Send".
I was just about to point out that.
The Italian proverb "Before speaking, count to ten" is insufficient. It should be changed to "... count to 120" at least.
Army1987 wrote:
"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.caha scritto:
>Army1987 <pl********@for.itwrote:
>>There is a sequence point after each conversion specifier in printf
First time I've ever seen that claim. Citation, please?
7.19.1p1:
The formatted input/output functions shall behave as if there is
a sequence point after the actions associated with each specifier.
It's 7.19.6. At least in N869.
--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
cbfalconer at maineline dot net
--
Posted via a free Usenet account from http://www.teranews.com
Army1987 said:
>
"CBFalconer" <cb********@yahoo.comha scritto nel messaggio
news:46***************@yahoo.com...
<snip>
>As written that function is a usage trap. One is likely to write something like:
printf("%s\n%s\n", str, rmtrail(str));
and expect to get two different strings. You won't.
Why? There is a sequence point after each conversion specifier in
printf, so the first %s will print the old str.
Irrelevant, since the evaluation of arguments will happen before printf
is even called, let alone at the point where it's wandering through its
format string.
But why listen to me? Watch, instead:
me@herecat foo.c
#include <stdio.h>
#include <string.h>
char *test(char *s)
{
strcpy(s, "If I see this twice, you're wrong.");
return s;
}
int main(void)
{
char buf[128] = "If I see this even once, you're right.";
printf("[%s]\n[%s]\n", buf, test(buf));
return 0;
}
me@here./foo
[If I see this twice, you're wrong.]
[If I see this twice, you're wrong.]
So either you're wrong, or gcc -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 is broken. Which do
you think is more likely?
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
"CBFalconer" <cb********@yahoo.comha scritto nel messaggio news:46***************@yahoo.com...
Army1987 wrote:
>"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.caha scritto:
>>Army1987 <pl********@for.itwrote:
There is a sequence point after each conversion specifier in printf
First time I've ever seen that claim. Citation, please?
7.19.1p1: The formatted input/output functions shall behave as if there is a sequence point after the actions associated with each specifier.
It's 7.19.6. At least in N869.
And so it is in n1124 (not sure about what was happening to me
yesterday...) This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Gama Franco |
last post by:
Hi,
I'm designing an interface for a shared library, and I would like to
know if there is a standard about how to return an object to the user. I
will use exceptions to report errors, so there...
|
by: Neal Coombes |
last post by:
Posted to comp.lang.c++.moderated with little response. Hoping for
better from the unmoderated groups:
-------- Original Message --------
Subject: Return appropriately by value, (smart)...
|
by: LaEisem |
last post by:
On-the-job, I have "inherited" a lot of old C language software.
A question or two about when "casting" of null pointer constants
is needed has occurred during behind-the-scenes cleanup
of some...
|
by: Isaac |
last post by:
Hi mates
I want to know a simple program of return array from function ? Do I
need to use pointer to return the address of the first element in an
array.
Isaac
|
by: Nascimento |
last post by:
Hello,
How to I do to return a string as a result of a function.
I wrote the following function:
char prt_tralha(int num)
{
int i;
char tralha;
| |
by: msolem |
last post by:
I have some code where there are a set of functions that return
pointers to each other. I'm having a bit of a hard time figuring out
the correct type to use to do that.
The code below works but...
|
by: zl2k |
last post by:
hi, c++ user
Suppose I constructed a large array and put it in the std::vector in a
function and now I want to return it back to where the function is called.
I can do like this:
...
|
by: Pedro Pinto |
last post by:
Hi there once more........
Instead of showing all the code my problem is simple.
I've tried to create this function:
char temp(char *string){
alterString(string);
return string;
|
by: Pietro Cerutti |
last post by:
i Group,
to my understanding, defining a function parameter as "const" means that
the function is not going to change it.
Why does the compiler says "return discards qualifiers from pointer...
|
by: Francois Grieu |
last post by:
When running the following code under MinGW, I get
realloc(p,0) returned NULL
Is that a non-conformance?
TIA,
Francois Grieu
#include <stdio.h>
#include <stdlib.h>
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
| |
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...
| |