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

Home Posts Topics Members FAQ

K&R p 130

mdh
Hi All,
Just when I thought things were going to get easy!

Structs.

I **thought** I had copied the examples pretty closely, but am getting
a number of errors.
The code:
>>>>>>
#include <stdio.h>
int main (int argc, const char * argv[]) {

struct point {
int x;
int y;
};
struct point makepoint( int, int); /* error. previous decl of
'makepoint' was here*/

struct point p1 = makepoint(8,9);

printf("%d, %d\n", p1.x, p1.y);
}


struct point makepoint(int x, int y) {
struct point temp;
temp.x = x;
temp.y = y;
return temp;
}

The error I got in the past has meant that something has been defined
twice, but as far as I can tell, ( probably incorrectly) I have
declared a struct called point, then declared a function which accepts
two integer arguments and returns a 'point' structure. Clearly I am
missing something.

In addition, I am getting a number of errors in makepoint function
defintion, which may become obvious once my initial query is cleared.
If not, I will ask then.

Lastly, K&R say , on p 130, of the makepoint function, "notice that
there is no conflict between the argument name and the member with the
same name". I assume that this refers to the lines

temp.x = x;
temp.y = y;

Thanks as usual.

Aug 17 '08
34 1939
Nick Keighley wrote:
On 17 Aug, 09:25, "Malcolm McLean" <regniz...@btin ternet.comwrote :
>"mdh" <m...@comcast.n etwrote in message

On Aug 16, 11:12 pm, santosh <santosh....@gm ail.comwrote:
>>So I once again ran into a scope issue? In this case block scope? vs
file scope which you implemented? Santosh, could you help me
understand why I can declare 'int foo(int);' within "main" and then
call it, but I cannot do the same with the struct?
The struct is not local to main. It is used in another function.
Similarly if you called foo() from anywhere except main(), you'd have to
prototype it again.
This is why we normally place structures and prototypes at the top of the
file, usually wrapped up into a header.

why "usually"?
The answer to that depends upon what you mean by that question. Are you
asking why it is usually the case, or are you asking why it is "only "
usually, and not "always"?

To answer the first question, it's usual because it is very common for
function prototypes and the structure definitions that they reference to
be used in multiple different source code files; the best way to make
sure that they are defined in a consistent fashion is to put them into a
single file which is #included into the other files.

If you're asking why this isn't "always" used, the answer is that not
all prototypes and structures are used in multiple source code files. If
they aren't, you can provide them in the one source code file where they
are actually used, so there's no need for a separate header file. This
has the advantage that you can know, with a certainty, that changes made
to such structure definitions will be seen only inside that source code
file, which makes maintenance easier.
Aug 18 '08 #21
mdh
On Aug 18, 4:58*am, James Kuyper <jameskuy...@ve rizon.netwrote:
>it's usual because it is very common for function prototypes and the structure definitions that they reference to be used in multiple different >source code files; the best way to make sure that they are defined in a consistent fashion is to put them into a
single file which is #included into the other files.

Does this not lead to multiple definitions of an object then and thus
an error? Or I have probably misunderstood you :-)
Aug 18 '08 #22
mdh wrote:
On Aug 18, 4:58 am, James Kuyper <jameskuy...@ve rizon.netwrote:
>it's usual because it is very common for function prototypes and the structure definitions that they reference to be used in multiple different >source code files; the best way to make sure that they are defined in a consistent fashion is to put them into a
single file which is #included into the other files.


Does this not lead to multiple definitions of an object then and thus
an error? Or I have probably misunderstood you :-)
I should have said structure declarations, not structure definitions.
Actual structure definitions do not belong in header files, for
precisely the reason you mention. However, structure types should be
declared in header files, if they are used in multiple source code files.
Aug 18 '08 #23
mdh
On Aug 17, 10:54*am, Barry Schwarz <schwa...@dqel. comwrote:
On Sun, 17 Aug 2008 08:37:55 -0700 (PDT), mdh <m...@comcast.n et>
wrote:
>
When I call "foo" in main, that identifier does "know" where to find
the definition of foo. The identifier "foo" though has block scope, if
I understand this correctly.
So, how then does the call to foo get handled correctly?

The call gets handled correctly because the linker, not the compiler,
is responsible for resolving the addresses.

Just saw your reply...thank you. .

Aug 19 '08 #24
>In article <87************ @bsb.me.ukBen Bacarisse <be********@bsb .me.uk>
wrote:
>>... Let me write [this] out compressed for convenience:

int main(void)
{
struct point { int x, y; }; /* The struct tag point has a */
struct point makepoint(int, int); /* meaning all the way down */
struct point p = makepoint(1, 2); /* to here... */
}

struct point makepoint(int a, int b) /* ... but not here where it */
{ /* is also needed. */
/* stuff */
}

Outside main, "struct point" has no meaning,
Well, this is not *strictly* true, but the rest is:
>>so the definition is rejected. The first error I get (always the
one to worry about) is "return type is an incomplete type" which
means "I don't know enough about struct point to make a function
return one".
In article <73************ *************** *******@i24g200 0prf.googlegrou ps.com>
mdh <md**@comcast.n etwrote:
>OK..., this is unique only to structs, unions and enums. And if so,
(Presumably the statement here -- ending with a period -- was
meant as a question.) Yes, it is in fact unique to those three.
>is this due to the complicated nature of those objects,
Not exactly. Instead, it is due to the fact that those three
things are the three ways that C allows users to define new
data-types.

The "struct" keyword does one of three things:

- refer to an existing struct type;
- declare a new, incomplete struct type; or
- define a new struct type (or -- really the same thing --
complete an incomplete one).

The union and enum keywords do the same; the only real difference
is when defining types (because a union defines a bunch of
"overlappin g" members, only one of which you can use at a time,
and an enum defines a bunch of integer constants).

You get a new type defined when you use a brace-enclosed list after
the keyword and (optional, in this case) tag. You refer back to
an existing type when you use a tag you already defined. You create
a new, incomplete type when you use a tag you have not yet defined.
In all three cases, assuming that you do in fact use a tag, you
write:

struct tag_name_goes_h ere /* and then some more stuff here... */

and I like to say that the tag is the "true name" of the type, but
it is not, quite.

Tag names have scope, like ordinary variable names and like function
names; but tag names have no linkage. When a tag name goes out of
scope, the type associated with that tag still exists, but can no
longer be named. You cannot even use linkage to get it back,
because the names have none.

If you only ever declare and/or define struct types at file scope,
the scope issue becomes irrelevant. It matters when you declare
and/or define them at block scopes, though (and, for that matter,
at function-prototype scopes). This is what Ben's compressed
example above does. The type "struct point" is declared-and-defined
(all at once) as the first code line within main(). The type
begins to exist at that point, and is name-able at that point.
The type still exists after the closing brace, but is no longer
name-able.

The subsequent "struct point" creates a *new* (and different)
user-defined type, also named "struct point", in the same way that
if you declared a new variable named "p" outside main() it would
be a new, different "p", even though main() also has a variable
named "p". Because there is no open brace after "struct point",
though, this new type is merely *declared*, not defined. It thus
becomes an incomplete type.

Normally, you can -- and people often do -- declare incomplete
types and then complete them later. This happens every time you
make self- or mutually-referential structures. (For self-referential
structures, it happens only because the type is not complete
until the closing brace that ends the member-list.) That is:

struct name_value_list {
struct name_value_list *next;
char *name;
int value;
};

or:

/* files open in the editor are represented by lists of blocks */
struct buffer_list {
struct file *containing_fil e;
struct buffer_list *forw, *back;
int used; /* amount of contents[] actually in use */
char contents[SIZE];
};
/* and there can be multiple open files */
struct file {
struct file *forw, *back;
struct buffer_list *head;
... other data here as needed ...
};

There is no way to rearrange the second pair of structures so that
both of them are completed before the second one is defined. :-)
So it is absolutely necessary to allow incomplete user-defined
types to exist, and in some cases, you can leave them incomplete
for an entire translation unit (provided you work only with pointers
to them, for instance -- this is a reasonable way to do "data
hiding": keeping client code from peeking into implementation
details that you would like to be able to change without notice).

The incomplete types arise as soon as the "struct" keyword (or
union or enum, for those two cases) is followed by a tag that
is not defined or declared yet. This does have one drawback: a
typo in a tag-name creates a new type, even if you did not mean
to. For instance:

struct list {
struct lsit *next;
... data members ...
};

This creates a "struct list", but its "next" member points to a
"struct lsit" instead of a "struct list", where presumably you
meant for it to point to another "struct list". When you try to
use p->next, you will get complaints, either about an incomplete
type (if you refer to p->next->field) or an incompatible type (if
you attempt to set p->next = new_list_elem, where new_list_elem is
a "struct list *"). This is, I think, one of several reasons that
some people like "typedef" aliases. (For more on this, see
<http://web.torek.net/torek/c/types2.html>.)

The same problem -- typographic errors -- can bite you with
function prototypes:

void print_list(stru ct lsit *); /* oops */

This declaration compiles well enough, because "struct lsit" is
created as a new, incomplete type with function-prototype scope.
The type becomes totally inaccessible as soon as the prototype
ends, though, so it is not very useful. At least one compiler
(gcc) warns if you do this. Note that the same problem hits you
even if you spell the type-name correctly, if you fail to provide
at least an incomplete declaration first:

double eval(struct tree *); /* evaluate expression tree */
struct tree *binary_op(int op, struct tree *, struct tree *);
...

The fix for this is to make sure that two word phrase "struct tree"
occurs at file scope *before* any of the parenthesized, function-prototype
scope mentions. In this case, rearranging the two function prototypes
will do the trick; or you can include an incomplete declaration:

struct tree;
double eval(struct tree *);
...

It is always OK to put in an "extra" incomplete declaration at file
scope: this is just saying "by the way, there is a user-defined
type named tree, at file scope", and if the compiler already knows
that, it shrugs its metaphorical shoulders, mutters "I knew that
already", and moves on. (But if it did not know that before, well,
it does now, and all is well.)

There are a couple more tricky bits involving tags and scope. If
you have a user-defined type at an outer scope level (such as "file
scope") and then use the same tag in an inner scope -- block or
prototype -- are you referring to the existing name, or creating
a new one? The answer is: "it depends". In most C code, people
mostly want to refer to the existing user-defined type, and this
happens entirely naturally:

struct list {
struct list *next;
...
};

void print_list(stru ct list *head) {
struct list *p;

for (p = head; p != NULL; p = p->next)
...
}

The "struct list" in the formal parameter ("head") and the local
variable ("p") declarations refers back to the file-scope "struct
list". If you want to override it, that also tends to happen
fairly naturally:

struct blah { char *argh; double yikes; };

void yucky_function( void) {
struct blah { int *p; long *q; } mess_o_pointers[10];
... code in here that uses "struct blah" refers to the
local one ...
}

struct blah *find_blah(char *name) {
... this code refers back to the file-scope "struct blah" ...
}

The exception occurs when you need mutually-referential structures
within a block, and are re-using a tag that you already used at
file scope. In this case, you have to use an "empty" declaration
to pave the way, much as with the "struct tree" example above. In
this case, the empty declaration pushes the outer-scope type aside
for the moment, creating a new, incomplete, inner-scope type:

void even_yuckier(vo id) {
struct blah; /* yet another different "struct blah" */
struct zorg { struct blah *p; ... };
struct blah { struct zorg *q; ... };
...
}

Without the empty declaration, "struct zorg"'s "struct blah *p"
member would refer to the file-scope "struct blah", not the
block-scope one.

(While I was writing this, I wondered again what happens with:

struct X;
struct X *global_px;
void f(void) {
struct X { int a; } localvar;
...
global_px = &localvar; /* error? or OK? */
...
}

Does the inner "struct X" complete the outer type, or does it create
a new type? I was never sure of the answer based on the C Standards,
but gcc, at least, creates a new inner struct, as shown by the fact
that the variable "localvar" has the wrong type, so that gcc prints
a diagnostic. If you *can* complete an outer incomplete type, this
might possibly lead to an interesting problem with typedef-names,
so gcc's result here is good. Whether it is standard-conforming,
I am not sure.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: gmail (figure it out) http://web.torek.net/torek/index.html
Aug 19 '08 #25
Chris Torek <no****@torek.n etwrites:
(While I was writing this, I wondered again what happens with:

struct X;
struct X *global_px;
void f(void) {
struct X { int a; } localvar;
...
global_px = &localvar; /* error? or OK? */
...
}

Does the inner "struct X" complete the outer type, or does it create
a new type? I was never sure of the answer based on the C Standards,
but gcc, at least, creates a new inner struct, as shown by the fact
that the variable "localvar" has the wrong type, so that gcc prints
a diagnostic. If you *can* complete an outer incomplete type, this
might possibly lead to an interesting problem with typedef-names,
so gcc's result here is good. Whether it is standard-conforming,
I am not sure.)
gcc has it right in this case. Both the outer 'struct X;' and
the inner 'struct X { int a; } localvar;' are declarations of
structure types (by 6.7.2.3 p 7 and 6.7.2.3 p 6, respectively).
Then we have 6.7.2.3 p 5, which says "Two declarations of structure,
union, or enumerated types which are in different scopes or use
different tags declare distinct types." Because the declarations
are in different scopes they must be distinct types.

(The 'struct X *global_px;' refers to the same type as 'struct X;'
by 6.7.2.3 p 9.)
Aug 19 '08 #26
mdh
On Aug 19, 12:59*am, Chris Torek <nos...@torek.n etwrote:
In article <874p5jpujw.... @bsb.me.ukBen Bacarisse <ben.use...@bsb .me.uk>
wrote:
>...
>Outside main, "struct point" has no meaning,

Well, this is not *strictly* true, but the rest is:
>
The "struct" keyword does one of three things:

* - refer to an existing struct type;
* - declare a new, incomplete struct type; or
* - define a new struct type (or -- really the same thing --
* * complete an incomplete one).



thank you for that extensive explanation
Aug 19 '08 #27
On Sun, 17 Aug 2008 08:00:52 -0700 (PDT), mdh posted:
On Aug 17, 7:47*am, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
>. *Let me write it out
compressed for convenience:

int main(void)
{
* * struct point { int x, y; }; * * * /* The struct tag point has a */
* * struct point makepoint(int, int); /* meaning all the way down */
* * struct point p = makepoint(1, 2); /* to here... */

}

struct point makepoint(int a, int b) /* ... but not here where it */
{ * * * * * * * * * * * * * * * * * */* is also needed. */
* /* stuff */

}

Outside main, "struct point" has no meaning, so the definition is
rejected.
[snipped mdh's comments]

Ben,

I don't know if you know it, but your usenet existence is somewhat
ethereal. I can't read your posts although I have the very good
news.individual .net.

You might want to think about a new NSP.
--
We are here and it is now. Further than that, all human knowledge is
moonshine. 3
H. L. Mencken
Aug 20 '08 #28
Chris Torek <no****@torek.n etwrites:
>>In article <87************ @bsb.me.ukBen Bacarisse <be********@bsb .me.uk>
wrote:
>>>... Let me write [this] out compressed for convenience:

int main(void)
{
struct point { int x, y; }; /* The struct tag point has a */
struct point makepoint(int, int); /* meaning all the way down */
struct point p = makepoint(1, 2); /* to here... */
}

struct point makepoint(int a, int b) /* ... but not here where it */
{ /* is also needed. */
/* stuff */
}

Outside main, "struct point" has no meaning,

Well, this is not *strictly* true, but the rest is:
Yes, I see. You are being kind. "struct point" means a lot outside
main -- I was abbreviating to a ridiculous extent. But I am glad I
made the mistake because it prompted an interesting reply!

<snipped>
--
Ben.
Aug 20 '08 #29
Ron Ford <ro*@example.in validwrites:
I don't know if you know it, but your usenet existence is somewhat
ethereal. I can't read your posts although I have the very good
news.individual .net.
Noted, but I am not sure what I can do. Every one of my posts (that
I've had reason to look for) has shown up in Google for example
(including all of my posts in this thread) but it is possible that my
server is blocked by some parts of Usenet...

Where is it topical to discuss/investigate this?

--
Ben.
Aug 20 '08 #30

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

Similar topics

9
8581
by: Collin VanDyck | last post by:
I have a basic understanding of this, so forgive me if I am overly simplistic in my explanation of my problem.. I am trying to get a Java/Xalan transform to pass through a numeric character reference (i.e.  ) and it seems to be converting the character to its UNICODE representation. Take this source XML document: <?xml version="1.0" encoding="UTF-8"?>
1
11445
by: DrTebi | last post by:
Hello, I have the following problem: I used to "encode" my email address within links, in order to avoid (most) email spiders. So I had a link like this: <a href="mailto:DrTebi@yahoo.com">DrTebi</a> This would work like a regular mailto link in any browser, but wouldn't be visible to spiders if they don't have a function to decode it.
0
2425
by: Thomas Scheffler | last post by:
Hi, I runned in trouble using XALAN for XSL-Transformation. The following snipplet show what I mean: <a href="http://blah.com/?test=test&amp;test2=test2">Test1&amp;</a> <a href="http://blah.com/?test=test&amp;amp;test2=test2">Test2&amp;amp;</a> This results in the following HTML Code:
4
3036
by: Luklrc | last post by:
Hi, I'm having to create a querysting with javascript. My problem is that javscript turns the "&" characher into "&amp;" when it gets used as a querystring in the url EG: /mypage.asp?value1=1&amp;value2=4&amp; ... which of course means nothing to asp.
4
3230
by: johkar | last post by:
When the output method is set to xml, even though I have CDATA around my JavaScript, the operaters of && and < are converted to XML character entities which causes errors in my JavaScript. I know that I could externalize my JavaScript, but that will not be practical throughout this application. Is there any way to get around this issue? Xalan processor. Stripped down stylesheet below along with XHTML output. <?xml version='1.0'?>...
8
2819
by: Nathan Sokalski | last post by:
I add a JavaScript event handler to some of my Webcontrols using the Attributes.Add() method as follows: Dim jscode as String = "return (event.keyCode>=65&&event.keyCode<=90);" TextBox2.Attributes.Add("onKeyPress", jscode) You will notice that jscode contains the JavaScript Logical And operator (&&). However, ASP.NET renders this as &amp;&amp; in the code that is
11
6447
by: Jeremy | last post by:
How can one stop a browser from converting &amp; to & ? We have a textarea in our system wehre a user can type in some html code and have it saved to the database. When the data is retireved and
14
5942
by: Arne | last post by:
A lot of Firefox users I know, says they have problems with validation where the ampersand sign has to be written as &amp; to be valid. I don't have Firefox my self and don't wont to install it only because of this, so I hope some of you gurus can enlighten me with this :) In what circumstances can the "&amp;" in the source code be involuntary changed to "&" by a browser when or other software, when editing and uploading the file to the web...
12
10124
by: InvalidLastName | last post by:
We have been used XslTransform. .NET 1.1, for transform XML document, Dataset with xsl to HTML. Some of these html contents contain javascript and links. For example: // javascript if (a &gt; b) ..... // xsl contents abc.aspx?p1=v1&amp;p2=<xsl:value-of select="$v2" />
7
4633
by: John Nagle | last post by:
I've been parsing existing HTML with BeautifulSoup, and occasionally hit content which has something like "Design & Advertising", that is, an "&" instead of an "&amp;". Is there some way I can get BeautifulSoup to clean those up? There are various parsing options related to "&" handling, but none of them seem to do quite the right thing. If I write the BeautifulSoup parse tree back out with "prettify", the loose "&" is still in there. So...
0
9708
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
9587
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
10340
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
10324
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
10085
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...
1
7623
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5527
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...
1
4302
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2998
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 can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.