473,804 Members | 3,607 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Comments on my code?

Hi-

I am learning C from some old lecture notes, but they don't have
solutions so I'd like some feedback on my code if anyone has the time.

This is an exercise: "Write a program to trim any leading whitespace
from a string and return a newly allocated buffer containing the trimmed
string. Don't forget to handle errors."

main(argc, argv)
int argc; char **argv;
{
char *strtrim(), *r=0;
puts(argc>1 && (r=strtrim(*++a rgv)) ? r : "Unspecifie d error");
free(r);
}

/* trims initial whitespace */
char *strtrim(s)
char *s;
{
char *r, *malloc();
for( ; isspace(*s); s++);
r=malloc(strlen (s)+1);
if(r)
strcpy(r,s);
return r;
}

This looks OK to me and works correctly, but the compiler produces some
mysterious warnings about conflicting definitions that I don't really
understand.
--
How come we never talk anymore?
Sep 1 '07
28 1691
Platonic Solid wrote:
>
I am learning C from some old lecture notes, but they don't have
solutions so I'd like some feedback on my code if anyone has the
time.

This is an exercise: "Write a program to trim any leading whitespace
from a string and return a newly allocated buffer containing the
trimmed string. Don't forget to handle errors."

main(argc, argv)
int argc; char **argv;
{
char *strtrim(), *r=0;
puts(argc>1 && (r=strtrim(*++a rgv)) ? r : "Unspecifie d error");
free(r);
.... snip ...
>
This looks OK to me and works correctly, but the compiler produces
some mysterious warnings about conflicting definitions that I
don't really understand.
To start with, you are failing to use prototypes (using obsolete
K&R 1 function headers), omitting necessary #includes, and using
system reserved names. The latter includes anything of the form
"strx..." where x is a lowercase letter.

You can get a satisfactory approximation to the standard in N869 or
N1124. You can find a suitable bzip2 compressed version of N869
at:

<http://cbfalconer.home .att.net/download/>

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 1 '07 #11
Platonic Solid wrote:
>
.... snip ...
>
OK, so that explains why strcpy produces a warning as it returns
char * and not int. But the compiler also complains about malloc
(I specifically supply the return type for that) and strlen, which
returns int so should be OK by Q 1.25.
You didn't give code, so we can't make suggestions. If you have
problems with malloc you are probably a) casting the return or b)
failing to include <stdlib.hor c) capturing the return value in
other than a pointer or d) using a C++ compiler.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 1 '07 #12
On 1 Sep 2007 at 16:42, CBFalconer wrote:
Platonic Solid wrote:
>>
... snip ...
>>
OK, so that explains why strcpy produces a warning as it returns
char * and not int. But the compiler also complains about malloc
(I specifically supply the return type for that) and strlen, which
returns int so should be OK by Q 1.25.

You didn't give code, so we can't make suggestions.
On the contrary, I posted my code, but here it is again:

main(argc, argv)
int argc; char **argv;
{
char *strtrim(), *r=0;
puts(argc>1 && (r=strtrim(*++a rgv)) ? r : "Unspecifie d error");
free(r);
}

/* trims initial whitespace */
char *strtrim(s)
char *s;
{
char *r, *malloc(), *strcpy();
for( ; isspace(*s); s++);
r=malloc(strlen (s)+1);
if(r)
strcpy(r,s);
return r;
}

(I've made one fix, by putting in the correct return type for strcpy)

If you have problems with malloc you are probably a) casting the
return or b) failing to include <stdlib.hor c) capturing the return
value in other than a pointer or d) using a C++ compiler.
On the contrary, I've declared malloc correctly and store its return
value in a char *.

I'm not sure what to do about people's advice that some of the syntax in
the lecture notes is now old-fashioned - as it still seems to compile
just fine, I'm tempted to stick with what I know.
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net>
--
How come we never talk anymore?
Sep 1 '07 #13
Platonic Solid wrote:
char *r, *malloc(), *strcpy();

On the contrary, I've declared malloc correctly and store its return
value in a char *.
No, you haven't declared malloc correctly.
Sep 1 '07 #14
Harald van Dijk <tr*****@gmail. comwrites:
Platonic Solid wrote:
> char *r, *malloc(), *strcpy();

On the contrary, I've declared malloc correctly and store its return
value in a char *.

No, you haven't declared malloc correctly.
Specifically, malloc returns void*, not char*, and it takes an
argument of type size_t. Since you didn't declare the argument type,
something as simple as malloc(42) invokes undefined behavior, since
you're passing an argument of type int.

If you had declared it correctly as
void *malloc(size_t) ;
then a call like malloc(42) would implicitly convert the argument to
size_t -- and a call with a non-numeric argument would trigger an
error message.

But the best way to provide the correct declaration is not to
manually re-write it yourself. It's to provide
#include <stdlib.h>
at the top of your source file. There's simply no good reason not to
do it that way.

The more correct information you can provide for the compiler, the
more it can help you. A lot of the facilities for this, particularly
function prototypes, were introduced with the ANSI C standard in 1989.

Prototypes were introduced into C 18 years ago. There are no longer
any significant compilers still being used that don't support them, so
there's no good reason not to use them, along with a number of other
features introduced by ANSI. (The latest ISO C standard, C99, hasn't
caught on as well, so there are still good reasons to avoid
C99-specific features.)

Your code is archaic. You can still write working archaic code if
you're careful enough, but you really should learn the language as it
is today. Reading K&R2 is probably the best way to do this.

--
Keith Thompson (The_Other_Keit h) 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"
Sep 1 '07 #15
On Sat, 01 Sep 2007 20:35:10 +0200, Platonic Solid wrote:
On the contrary, I've declared malloc correctly and store its return
value in a char *.

I'm not sure what to do about people's advice that some of the syntax in
the lecture notes is now old-fashioned - as it still seems to compile
just fine, I'm tempted to stick with what I know.
But, in ANSI/ISO C, which has been around since 1989 and radically
revised in 1999 (even though this last version isn't widely
implemented yet), malloc() returns a void *, not a char * anymore.
It is very likely to work, since char* and void* are required to
have the same alignment etc., but probably a sufficiently deep
level of language lawyering would show that the behavior is
undefined by the International Standard.

Also, nowadays it is common to declare library functions with the
prototypes in the corresponding headers. For example, stdlib.h
contains a correct prototype for malloc(), and you can add it to
your code with the preprocessing directive
#include <stdlib.h>
which gets replaced with the contents of that file.
In C99 you *always* must declare functions, even if they return an
int, and doing so is a very good idea in C89, too.
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower

Sep 1 '07 #16
On Sep 1, 8:22 pm, Keith Thompson <ks...@mib.orgw rote:
Harald van D k <true...@gmail. comwrites:
Platonic Solid wrote:
char *r, *malloc(), *strcpy();
On the contrary, I've declared malloc correctly and store its return
value in a char *.
No, you haven't declared malloc correctly.

Specifically, malloc returns void*, not char*, and it takes an
argument of type size_t. Since you didn't declare the argument type,
something as simple as malloc(42) invokes undefined behavior, since
you're passing an argument of type int.

If you had declared it correctly as
void *malloc(size_t) ;
then a call like malloc(42) would implicitly convert the argument to
size_t -- and a call with a non-numeric argument would trigger an
error message.
Am I right in thinking that first standard promotions would apply, and
only then would the result be converted to size_t?
But the best way to provide the correct declaration is not to
manually re-write it yourself. It's to provide
#include <stdlib.h>
at the top of your source file. There's simply no good reason not to
do it that way.

The more correct information you can provide for the compiler, the
more it can help you. A lot of the facilities for this, particularly
function prototypes, were introduced with the ANSI C standard in 1989.

Prototypes were introduced into C 18 years ago. There are no longer
any significant compilers still being used that don't support them, so
there's no good reason not to use them, along with a number of other
features introduced by ANSI. (The latest ISO C standard, C99, hasn't
caught on as well, so there are still good reasons to avoid
C99-specific features.)

Your code is archaic. You can still write working archaic code if
you're careful enough, but you really should learn the language as it
is today. Reading K&R2 is probably the best way to do this.

--
Keith Thompson (The_Other_Keit h) 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"

Sep 1 '07 #17
Platonic Solid wrote:
On 1 Sep 2007 at 16:42, CBFalconer wrote:
>Platonic Solid wrote:
... snip ...
>>OK, so that explains why strcpy produces a warning as it returns
char * and not int. But the compiler also complains about malloc
(I specifically supply the return type for that) and strlen, which
returns int so should be OK by Q 1.25.
You didn't give code, so we can't make suggestions.

On the contrary, I posted my code, but here it is again:

main(argc, argv)
int argc; char **argv;
{
char *strtrim(), *r=0;
puts(argc>1 && (r=strtrim(*++a rgv)) ? r : "Unspecifie d error");
free(r);
}

/* trims initial whitespace */
char *strtrim(s)
char *s;
{
char *r, *malloc(), *strcpy();
for( ; isspace(*s); s++);
r=malloc(strlen (s)+1);
if(r)
strcpy(r,s);
return r;
}

(I've made one fix, by putting in the correct return type for strcpy)
Yabbut, that's the wrong way to do it, and it still
doesn't fix the incorrect declaration of strlen(). The
right fix (hint: Have you learned about the #include
directive yet?) would take care of both problems, and
would enable the compiler to catch errors like strcpy(x)
or strlen(x, y), too.
>If you have problems with malloc you are probably a) casting the
return or b) failing to include <stdlib.hor c) capturing the return
value in other than a pointer or d) using a C++ compiler.

On the contrary, I've declared malloc correctly and store its return
value in a char *.
You have declared malloc *in*correctly. The cure is
similar to that for strlen() et al.
I'm not sure what to do about people's advice that some of the syntax in
the lecture notes is now old-fashioned - as it still seems to compile
just fine, I'm tempted to stick with what I know.
I bet your 1955 Studebaker runs just fine without those
pesky seat belts, air bags, anti-lock brakes, and emission-
control devices, too.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Sep 1 '07 #18
On 2007-09-01 18:35, Platonic Solid <pl*****@mailin ator.comwrote:
main(argc, argv)
int argc; char **argv;
{
char *strtrim(), *r=0;
puts(argc>1 && (r=strtrim(*++a rgv)) ? r : "Unspecifie d error");
free(r);
}

/* trims initial whitespace */
char *strtrim(s)
char *s;
{
char *r, *malloc(), *strcpy();
for( ; isspace(*s); s++);
r=malloc(strlen (s)+1);
if(r)
strcpy(r,s);
return r;
}
[...]
On the contrary, I've declared malloc correctly
No, you haven't.
and store its return value in a char *.

I'm not sure what to do about people's advice that some of the syntax in
the lecture notes is now old-fashioned - as it still seems to compile
just fine, I'm tempted to stick with what I know.
It *seems* to compile fine. It also *seems* to execute fine on your
system. But it's still wrong, and works only by chance. It may not work
on a different system.

For example, you haven't defined strlen, so the compiler has to assume
it returns an int. But it returns a size_t and a size_t may be returned
differently than an int (for example, on the 8086, in some memory
models, a size_t was returned in a pair of registers, but an int in only
one register. Declaring strlen as an int instead of a size_t would yield
wrong results if the string was longer than 32767 characters).

Then you pass the int which is the result of strlen(s)+1 to malloc.
Since no prototype is in scope, the compiler has to assume that malloc
expects an int, when really it expects a size_t. Using the example of
the 8086 compiler again, malloc would take 4 bytes off the stack, but
strtrim put only 2 bytes there, so the other two bytes contain some
random garbage (maybe the uninitialized value of r, or a part of the
value of s from the call to isspace). So malloc may try to allocate some
ridiculous amount of memory (basically rand() * 65536 + strlen(s)+1) and
fail. So strtrim also fails.

(This is harder to demonstrate with 64 bit processors: The calling
convention for x86_64 is to pass the first 6 parameters in registers, so
an int/size_t mismatch matters only if it happens in 7th or later
parameter. But assuming you can be sloppy if you only have functions
with 6 or less parameters sounds like an extremely bad idea to me)

As an erstwhile regular in this group wrote: "If you lie to the compiler
it will get its revenge!"

hp

--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hj*@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
Sep 1 '07 #19
Fr************@ googlemail.com wrote:
On Sep 1, 8:22 pm, Keith Thompson <ks...@mib.orgw rote:
>Harald van D k <true...@gmail. comwrites:
Platonic Solid wrote:
char *r, *malloc(), *strcpy();
>On the contrary, I've declared malloc correctly and store its return
value in a char *.
No, you haven't declared malloc correctly.

Specifically , malloc returns void*, not char*, and it takes an
argument of type size_t. Since you didn't declare the argument type,
something as simple as malloc(42) invokes undefined behavior, since
you're passing an argument of type int.

If you had declared it correctly as
void *malloc(size_t) ;
then a call like malloc(42) would implicitly convert the argument to
size_t -- and a call with a non-numeric argument would trigger an
error message.

Am I right in thinking that first standard promotions would apply, and
only then would the result be converted to size_t?
Compare these functions:

unsigned short f1 (x)
unsigned short x;
{
return x;
}

unsigned short f2 (unsigned short x)
{
return x;
}

int main(void) {
unsigned short x = 3;
return f1(x) - f2(x);
}

The call to f1 results in x being promoted to int (or unsigned int,
depending on the system), and then converted back to unsigned short. The
call to f2 does not cause x to undergo any promotion to int. The given
declaration of malloc falls in the same category as f2, not f1. However, I
would be very surprised to find an implementation for which the end result
is any different for integer types.
Sep 1 '07 #20

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

Similar topics

4
3381
by: Sims | last post by:
Hi, I proud myself in having good comments, (/**/, // etc...), all over my scripts as well as a very descriptive section at the beginning of the script. No correct me if i am wrong but php must still 'read' those comments? So, do comments technically slow the whole process? Or is the loss of CPU/Time/memory so negligible that i do not need to worry about it.
17
2755
by: lkrubner | last post by:
I've got a PHP application that's 2 megs in size. Of that, my guess is 200k-400k is comments. Do they impose a performance hit? I've been postponing any kind of optimization, but at some point I'll have to do it. Is taking out the comments worth it? Of all the optimizations I can do, where should it rank?
28
3466
by: Benjamin Niemann | last post by:
Hello, I've been just investigating IE conditional comments - hiding things from non-IE/Win browsers is easy, but I wanted to know, if it's possible to hide code from IE/Win browsers. I found <!> in the original MSDN documentation, but this is (although it is working) unfortunately non-validating gibberish. So I fooled around trying to find a way to make it valid. And voila: <!--><!><!-->
10
2102
by: Monk | last post by:
Hi, Have a query regarding comments that extend over multiple-lines. Would like to know if the standard's view of this, so that we can create a code which doesn't run into compiler specific issues. 1. A normal comments is /* comment text */ 2. A multiple line comment is
40
4649
by: Edward Elliott | last post by:
At the risk of flogging a dead horse, I'm wondering why Python doesn't have any multiline comments. One can abuse triple-quotes for that purpose, but that's obviously not what it's for and doesn't nest properly. ML has a very elegant system for nested comments with (* and *). Using an editor to throw #s in front of every line has limitations. Your editor has to support it and you have to know how to use that feature. Not exactly...
98
4632
by: tjb | last post by:
I often see code like this: /// <summary> /// Removes a node. /// </summary> /// <param name="node">The node to remove.</param> public void RemoveNode(Node node) { <...> }
2
7342
by: beatTheDevil | last post by:
Hey guys, As the title says I'm trying to make a regular expression (regex/regexp) for use in removing the comments from code. In this case, this particular regex is meant to match /* ... */ comments. I'm using Ruby v.1.8.6 Here's my regex: multiline_comments = /\/\*(.*?)\*\// When I try myStr.gsub(multiline_comments, "")
2
5389
by: mad.scientist.jr | last post by:
In .NET 2.0, is there any way to include comments in the aspx file that do not get rendered to the client (ie no <!-- -->) ? When I try to include C# comments in a code block in an aspx page, like this: <% // ******************************************************* // CHANGE HISTORY: // DATE USER CHANGE
6
12001
by: Marjeta | last post by:
I was trying to compare a particular trigger on multiple servers. First I tried phpMyAdmin to script the trigger code, which unfortunately only worked on one server that has newer version of phpMyAdmin... Then I used mysqldump, which scripted trigger code on all the servers, bur with comments around all the trigger related code: phpMyAdmine scripted trigger code without comments. Why are those comments there? I searched thru...
0
9706
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9579
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10571
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10326
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10317
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10075
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6851
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5520
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5651
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.