473,503 Members | 1,706 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Return pointer from function

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...

Jun 27 '07 #1
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
Jun 27 '07 #2
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.

Jun 27 '07 #3
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

Jun 27 '07 #4
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"
Jun 27 '07 #5
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.
Jun 27 '07 #6
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#.
Jun 27 '07 #7
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
Jun 27 '07 #8

"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.
Jun 29 '07 #9
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
Jun 29 '07 #10

"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.
Jun 29 '07 #11
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
Jun 29 '07 #12

"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.
Jun 29 '07 #13
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

Jun 29 '07 #14
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
Jun 30 '07 #15

"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...)
Jun 30 '07 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
1996
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...
5
3029
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)...
10
2587
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...
4
157973
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
23
3547
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;
4
6932
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...
32
69638
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: ...
18
4024
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;
17
12738
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...
9
3788
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>
0
7083
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...
0
7328
jinu1996
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...
0
7456
tracyyun
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...
1
5011
isladogs
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...
0
4672
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...
0
3166
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...
0
3153
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
734
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
379
bsmnconsultancy
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...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.