Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > difference between pointers

Reply
Thread Tools

difference between pointers

 
 
Keith Thompson
Guest
Posts: n/a
 
      04-02-2013
Tim Rentsch <(E-Mail Removed)> writes:
> Keith Thompson <(E-Mail Removed)> writes:
>> Tim Rentsch <(E-Mail Removed)> writes:
>>> Keith Thompson <(E-Mail Removed)> writes:

>> [...]
>>>> You're assuming that this:
>>>>
>>>> d1 = &a; /* where d1 and a are both of type int */
>>>>
>>>> specifies a conversion. Nothing in the C standard says or implies
>>>> that. The types int and int* are not assignment-compatible, so
>>>> the assignment is a constraint violation, requiring a diagnostic.
>>>> *If* the compiler chooses to generate an executable after issuing
>>>> the diagnostic, nothing in the C standard says anything about how
>>>> it behaves. [...] a conforming implementation could do *anything*.
>>>> [snip elaboration]
>>>
>>> I'm not sure what your reasoning is to reach this conclusion.
>>> Certainly this assignment has a constraint violation, but you're
>>> saying, in effect, that it has undefined behavior. Presumably
>>> the underlying reasoning is one of two things, namely:
>>>
>>> A. There is a constraint violation, and any constraint
>>> violation is necessarily undefined behavior; or
>>>
>>> B. The assignment statement is trying to assign a pointer
>>> type to an integer type, and nothing in the Standard
>>> says how to do that, so there is undefined behavior.
>>>
>>> IMO point A is incorrect, although I would agree the point
>>> is debatable. Section 4 paragraph 3 says in part:
>>>
>>> If a ``shall'' or ``shall not'' requirement that appears
>>> outside of a constraint or runtime-constraint is violated,
>>> the behavior is undefined.

>>
>> IMHO A is correct (programs with constraint violations have
>> undefined behavior), though I'm not sure I can prove it.
>>
>>> This statement makes it reasonable to infer that a constraint
>>> violation might _not_ result in undefined behavior in some
>>> instances, as otherwise there is no point in excluding it.
>>> ("The exception proves the rule in cases not excepted.")

>>
>> Perhaps, but only if the behavior is actually defined somewhere.

>
> The behavior is defined by the semantics paragraphs of "Simple
> assignment", which the expression in question must have been
> identified as being. (This point expanded on below.)


Well, yes, but more on that below.

>>> Turning to point B, I think it is clearly just wrong, because
>>> of 6.5.16.1 p 2.

>>
>> Which says:
>>
>> In *simple assignment* (=), the value of the right operand is
>> converted to the type of the assignment expression and
>> replaces the value stored in the object designated by the left
>> operand.
>>
>> That's an interesting point, but consider the definition of
>> "constraint" in 3.8:
>>
>> restriction, either syntactic or semantic, by which the exposition
>> of language elements is to be interpreted
>>
>> So the statement about the semantics of a simplea ssignment "is to
>> be interpreted" in the context of the restriction on the operands.
>> My conclusion from that is that if the constraint is violated,
>> the statement doesn't apply.
>>
>> If the constraint is violated, it isn't a simple assignment.
>> We don't know what it is, but it's not part of a valid C program.

>
> The problem with this reasoning is that the compiler must have
> identified the expression as a simple assignment, because the
> constraint only applies to simple assignments, and violating a
> constraint requires a diagnostic. If we don't know that the
> expression is a simple assignment, then there is no constraint
> violation, and the compiler would be free to treat the program as
> having undefined behavior, without issuing a diagnostic. This is
> a classic "you can't have it both ways" kind of situation. The
> only reasonable way out is to say the compiler must identify the
> expression in question as a simple assignment, and proceed
> accordingly.


I went a little overboard saying that it isn't a simple assignment.
Syntactically, it clearly is.

But once the compiler recognizes it as a simple assignment, how
far must it "proceed accordingly"?

Semantically, it violates a constraint. A constraint is by
definition a "restriction, either syntactic or semantic, by which
the exposition of language elements is to be interpreted". I admit
that's a bit vague, but what I get from that is that violating
a constraint invalidates the exposition. My reading of 6.5.16.1
is roughly "*If* the following constraints are satisified *then* a
simple assignment has the following semantics." That's not the only
possible reading, of course, but it's the only one I can think of
that causes the definition of "constraint" to make sense.

And it turns out I've asked about this in comp.std.c several times
over the years (apparently I've been posting here long enough that
I sometimes forget things I've discussed before):

https://groups.google.com/forum/?fro....c/WNVXRSCqrGU
https://groups.google.com/forum/?fro....c/3Nu8-vlJOEU
https://groups.google.com/forum/?fro....c/M2UxT1wk1xQ

The threads are interesting reading if you're into that kind of thing.
Several people strongly stated their opinion that program that violate
constraints have undefined behavior, but I wasn't convinced that any of
them proved it.

One relevant post from 2007 (note that Doug Gwyn is a member of the
Committee):

https://groups.google.com/group/comp...ain&noredirect

"Douglas A. Gwyn" <(E-Mail Removed)> writes:
[...]
> Issuance of a "diagnostic" (meeting the implementation definition for
> identification, required for conformance to the C standard) implies
> rejection of the program (again, insofar as conformance is concerned).
> If an implementation wants to proceed to do something further with
> the translation unit, typically to continue processing to potentially
> generate additional diagnostics but also to go ahead and produce
> object code, then that is its business and it is allowed to do so.


I like that interpretation, and I wish it were clearly stated in the
standard.

I think the bottom line is that the standard is unclear about
the semantics, if any, of programs that violate constraints, and
particularly about the definition of "constraint". A clear statement
in the standard (even in a note) that any program that violates a
constraint, if it's accepted, has undefined behavior would settle
the issue. A clear statement of the opposite would do so as well.

*If* my interpretation is correct, then the cases where a description
of the semantics applies even when a constraint is violated (as in
the definition of simple assignment) can be explained as avoiding
redundancy. Yes the semantics section under "Simple assignment"
says that the RHS is converted to the type of the LHS; it doesn't
say *again* that the type must meet the constraints because that's
already been stated.

It seems odd to me to permit a compiler to reject a given construct,
but to impose specific requirements on its behavior if it's accepted.
A programmer cannotr reasonably depend on such a guarantee. On the
other hand, there are plenty of things in the standard that I find
odd, so that doesn't prove anything.

[SNIP]

> To try to bring the conversation up a level: the essential point I
> was trying to make is that the question is not black and white.
> Reasonable people can disagree here.


I believe we've demonstrated that by being reasonable people
disagreeing about it. }

> In the interest of giving a
> fair presentation under such circumstances, I think it's better to
> give a qualified statement rather than treating the matter as
> completely settled.


Hmm. Feel free to assume that anything posted under my name is prefixed
with "In my opinion, ".

[snip]

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
Nick Bowler
Guest
Posts: n/a
 
      04-02-2013
On Tue, 02 Apr 2013 14:48:43 +0000, army1987 wrote:
> On Sat, 30 Mar 2013 11:13:50 -0700, Tim Rentsch wrote:
>> There is no guarantee that a pointer to any type other than void can be
>> converted to any integer type other than _Bool. A pointer to void can
>> be converted to the types [u]intptr_t, but only if the implementation
>> defines them, which the Standard does not require.


This is not quite correct. Any pointer type can be converted to any
integer type. In most cases, however, the result is implementation-
defined.

> Is there any good reason why (intptr_t)&i isn't required to be the same
> as (intptr_t)(void *)&i? (Crossposted to comp.std.c.)


The literal text of the standard only requires the conversion to
(u)intptr_t and back again to work for "any valid pointer to void".
As there is a similar requirement for conversions of other kinds of
object pointers to void * and back again, I can't think of a good
reason for why there is no requirement for conversion of other sorts of
object pointers to (u)intptr_t and back again to work.

If I encountered an implementation which provides (u)intptr_t but
conversions of non-void object pointers and back again did not work, I
would assume that this was either the result of malice on the part of the
implementators, or maybe they just ported some code from the DeathStation
9000.

Fortunately, in this situation the craziness would have to be documented
as the result is squarely in implementation-defined territory.
 
Reply With Quote
 
 
 
 
Tim Rentsch
Guest
Posts: n/a
 
      04-02-2013
army1987 <(E-Mail Removed)> writes:

> On Sat, 30 Mar 2013 11:13:50 -0700, Tim Rentsch wrote:
>
>> There is no guarantee that a pointer to any type other than void can be
>> converted to any integer type other than _Bool. A pointer to void can
>> be converted to the types [u]intptr_t, but only if the implementation
>> defines them, which the Standard does not require.

>
> Is there any good reason why (intptr_t)&i isn't required to be the same
> as (intptr_t)(void *)&i? (Crossposted to comp.std.c.)


The pointer types (int *) and (void *) don't necessarily have
the same representation, or even the same size. The most
natural way of effecting a pointer-to-integer conversion is
just to copy the bits of the pointer into the bits of the
integer object representation. Obviously if we start with
a different representation, or even worse a different size,
that could affect the results.
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      04-02-2013
Keith Thompson <(E-Mail Removed)> writes:

> Tim Rentsch <(E-Mail Removed)> writes:
>> Keith Thompson <(E-Mail Removed)> writes:
>>> Tim Rentsch <(E-Mail Removed)> writes:
>>>> Keith Thompson <(E-Mail Removed)> writes:
>>> [...]
>>>>> You're assuming that this:
>>>>>
>>>>> d1 = &a; /* where d1 and a are both of type int */
>>>>>
>>>>> specifies a conversion. Nothing in the C standard says or implies
>>>>> that. The types int and int* are not assignment-compatible, so
>>>>> the assignment is a constraint violation, requiring a diagnostic.
>>>>> *If* the compiler chooses to generate an executable after issuing
>>>>> the diagnostic, nothing in the C standard says anything about how
>>>>> it behaves. [...] a conforming implementation could do *anything*.
>>>>> [snip elaboration]
>>>>
>>>> I'm not sure what your reasoning is to reach this conclusion.
>>>> Certainly this assignment has a constraint violation, but you're
>>>> saying, in effect, that it has undefined behavior. Presumably
>>>> the underlying reasoning is one of two things, namely:
>>>>
>>>> A. There is a constraint violation, and any constraint
>>>> violation is necessarily undefined behavior; or
>>>>
>>>> B. The assignment statement is trying to assign a pointer
>>>> type to an integer type, and nothing in the Standard
>>>> says how to do that, so there is undefined behavior.
>>>>
>>>> IMO point A is incorrect, although I would agree the point
>>>> is debatable. Section 4 paragraph 3 says in part:
>>>>
>>>> If a ``shall'' or ``shall not'' requirement that appears
>>>> outside of a constraint or runtime-constraint is violated,
>>>> the behavior is undefined.
>>>
>>> IMHO A is correct (programs with constraint violations have
>>> undefined behavior), though I'm not sure I can prove it.
>>>
>>>> This statement makes it reasonable to infer that a constraint
>>>> violation might _not_ result in undefined behavior in some
>>>> instances, as otherwise there is no point in excluding it.
>>>> ("The exception proves the rule in cases not excepted.")
>>>
>>> Perhaps, but only if the behavior is actually defined somewhere.

>>
>> The behavior is defined by the semantics paragraphs of "Simple
>> assignment", which the expression in question must have been
>> identified as being. (This point expanded on below.)

>
> Well, yes, but more on that below.
>
>>>> Turning to point B, I think it is clearly just wrong, because
>>>> of 6.5.16.1 p 2.
>>>
>>> Which says:
>>>
>>> In *simple assignment* (=), the value of the right operand is
>>> converted to the type of the assignment expression and
>>> replaces the value stored in the object designated by the left
>>> operand.
>>>
>>> That's an interesting point, but consider the definition of
>>> "constraint" in 3.8:
>>>
>>> restriction, either syntactic or semantic, by which the exposition
>>> of language elements is to be interpreted
>>>
>>> So the statement about the semantics of a simplea ssignment "is to
>>> be interpreted" in the context of the restriction on the operands.
>>> My conclusion from that is that if the constraint is violated,
>>> the statement doesn't apply.
>>>
>>> If the constraint is violated, it isn't a simple assignment.
>>> We don't know what it is, but it's not part of a valid C program.

>>
>> The problem with this reasoning is that the compiler must have
>> identified the expression as a simple assignment, because the
>> constraint only applies to simple assignments, and violating a
>> constraint requires a diagnostic. If we don't know that the
>> expression is a simple assignment, then there is no constraint
>> violation, and the compiler would be free to treat the program as
>> having undefined behavior, without issuing a diagnostic. This is
>> a classic "you can't have it both ways" kind of situation. The
>> only reasonable way out is to say the compiler must identify the
>> expression in question as a simple assignment, and proceed
>> accordingly.

>
> I went a little overboard saying that it isn't a simple assignment.
> Syntactically, it clearly is.
>
> But once the compiler recognizes it as a simple assignment, how
> far must it "proceed accordingly"?
>
> Semantically, it violates a constraint. A constraint is by
> definition a "restriction, either syntactic or semantic, by which
> the exposition of language elements is to be interpreted". I admit
> that's a bit vague, but what I get from that is that violating
> a constraint invalidates the exposition. My reading of 6.5.16.1
> is roughly "*If* the following constraints are satisified *then* a
> simple assignment has the following semantics." That's not the only
> possible reading, of course, but it's the only one I can think of
> that causes the definition of "constraint" to make sense.


My reading is that it places limits on what must be accepted by
the compiler but doesn't otherwise change the applicable semantic
descriptions. This shouldn't be a strange idea, as after all it
is what people expect for environmental limits -- the compiler
may reject any program that exceeds an environmental limit, but
if the program is accepted then the compiler better follow the
given semantic descriptions. I think the difference is primarily
one of expectation -- we expect a constraint violation will
result in a program being rejected, whereas we hardly ever expect
a program will be rejected because an environmental limit was
exceeded (and certainly the hope is that the program will not be
rejected!).

> And it turns out I've asked about this in comp.std.c several times
> over the years (apparently I've been posting here long enough that
> I sometimes forget things I've discussed before):
>
> https://groups.google.com/forum/?fro....c/WNVXRSCqrGU
> https://groups.google.com/forum/?fro....c/3Nu8-vlJOEU
> https://groups.google.com/forum/?fro....c/M2UxT1wk1xQ
>
> The threads are interesting reading if you're into that kind of thing.
> Several people strongly stated their opinion that program that violate
> constraints have undefined behavior, but I wasn't convinced that any of
> them proved it.


I expect there is some interesting reading there. I would be
more enthusiastic if the "improved" Google groups interface
weren't so abysmally bad.

> One relevant post from 2007 (note that Doug Gwyn is a member of the
> Committee):
>
> https://groups.google.com/group/comp...ain&noredirect
>
> "Douglas A. Gwyn" <(E-Mail Removed)> writes:
> [...]
> > Issuance of a "diagnostic" (meeting the implementation definition for
> > identification, required for conformance to the C standard) implies
> > rejection of the program (again, insofar as conformance is concerned).
> > If an implementation wants to proceed to do something further with
> > the translation unit, typically to continue processing to potentially
> > generate additional diagnostics but also to go ahead and produce
> > object code, then that is its business and it is allowed to do so.

>
> I like that interpretation, and I wish it were clearly stated in the
> standard.


Note that the long paragraph doesn't say one way or the other as
to whether the proceeding compilation is obliged to honor other
semantic descriptions that are well-defined. The author may have
a position on the subject, but I don't think this paragraph
clearly expresses it.

> I think the bottom line is that the standard is unclear about
> the semantics, if any, of programs that violate constraints, and
> particularly about the definition of "constraint". A clear statement
> in the standard (even in a note) that any program that violates a
> constraint, if it's accepted, has undefined behavior would settle
> the issue. A clear statement of the opposite would do so as well.


I agree 100%.

> *If* my interpretation is correct, then the cases where a description
> of the semantics applies even when a constraint is violated (as in
> the definition of simple assignment) can be explained as avoiding
> redundancy. Yes the semantics section under "Simple assignment"
> says that the RHS is converted to the type of the LHS; it doesn't
> say *again* that the type must meet the constraints because that's
> already been stated.
>
> It seems odd to me to permit a compiler to reject a given construct,
> but to impose specific requirements on its behavior if it's accepted.
> A programmer cannotr reasonably depend on such a guarantee. On the
> other hand, there are plenty of things in the standard that I find
> odd, so that doesn't prove anything.


It doesn't seem so odd to me because there are at least two other
cases where the Standard does just that, those being exceeding an
environment limit and use of a conditionally present feature (of
which C11 has too many IMO, but that is a separate discussion).

> [SNIP]
>
>> To try to bring the conversation up a level: the essential point I
>> was trying to make is that the question is not black and white.
>> Reasonable people can disagree here.

>
> I believe we've demonstrated that by being reasonable people
> disagreeing about it. }


Just so.

>> In the interest of giving a
>> fair presentation under such circumstances, I think it's better to
>> give a qualified statement rather than treating the matter as
>> completely settled.

>
> Hmm. Feel free to assume that anything posted under my name is prefixed
> with "In my opinion, ".


There are two reasons why I hope you'll reconsider this response.

First, I don't think it's really an accurate description all the
time. Some of the things you say you consider (I believe) to be
simply indisputable, ie, that no reasonable (and informed) person
would disagree. For example, the printf() statement you mentioned
earlier as not being strictly conforming -- this is not just an
opinion, as it cannot be reasonably disputed. It is valuable to
distinguish these two kinds of situations.

Second, and probably more important, I'm not the only audience for
your comments. Lots of people read what you have to say, and it
helps them understand not just the language but also the culture
of people who are interested in the language definition, and how
firm or weak the consensus is in different areas. IMO you would
be doing them a disservice to voice statements of opnion as if
they are statements of fact, or to not distinguish between cases
where you are giving a statement of opinion and where you feel
there is overwhelming consensus on a particular issue. By all
means, in any case where you feel there is overwhelming consensus,
please go ahead and respond unequivocally. In other cases,
however, where there is not such a strong consensus, and you
think reasonable people can disagree, I hope you'll agree that
it is better to express such remarks in a qualified way, so
readers get a more rounded view of the discussional landscape.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      04-02-2013
Jorgen Grahn <(E-Mail Removed)> writes:
> On Tue, 2013-04-02, Tim Rentsch wrote:
>> Varun Tewari <(E-Mail Removed)> writes:
>>
>>> Yep it did give warning. Thnx for pointing the correct gcc option for
>>> correct ansi parsing.

>>
>> You may also want to try
>>
>> gcc -std=c99 -pedantic-errors

> ...
>> gcc -std=c11 -pedantic-errors

>
> I strongly recommend
>
> -std=something -Wall -Wextra -pedantic -O2


Why -O2 rather than -O3?

> It's a good start for new code: a warning level that is high, but not
> so high that you have to make your code less readable to please the
> compiler.
>
> I also recommend reading the compiler manual, to get familiar with the
> different options.


--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Les Cargill
Guest
Posts: n/a
 
      04-02-2013
Keith Thompson wrote:
> Jorgen Grahn <(E-Mail Removed)> writes:
>> On Tue, 2013-04-02, Tim Rentsch wrote:
>>> Varun Tewari <(E-Mail Removed)> writes:
>>>
>>>> Yep it did give warning. Thnx for pointing the correct gcc option for
>>>> correct ansi parsing.
>>>
>>> You may also want to try
>>>
>>> gcc -std=c99 -pedantic-errors

>> ...
>>> gcc -std=c11 -pedantic-errors

>>
>> I strongly recommend
>>
>> -std=something -Wall -Wextra -pedantic -O2

>
> Why -O2 rather than -O3?
>


Ozone is a pollutant?

>> It's a good start for new code: a warning level that is high, but not
>> so high that you have to make your code less readable to please the
>> compiler.
>>
>> I also recommend reading the compiler manual, to get familiar with the
>> different options.

>



--
Les Cargill

 
Reply With Quote
 
Jorgen Grahn
Guest
Posts: n/a
 
      04-03-2013
On Tue, 2013-04-02, Keith Thompson wrote:
> Jorgen Grahn <(E-Mail Removed)> writes:
>> On Tue, 2013-04-02, Tim Rentsch wrote:
>>> Varun Tewari <(E-Mail Removed)> writes:
>>>
>>>> Yep it did give warning. Thnx for pointing the correct gcc option for
>>>> correct ansi parsing.
>>>
>>> You may also want to try
>>>
>>> gcc -std=c99 -pedantic-errors

>> ...
>>> gcc -std=c11 -pedantic-errors

>>
>> I strongly recommend
>>
>> -std=something -Wall -Wextra -pedantic -O2

>
> Why -O2 rather than -O3?


I included the optimization option because at least historically you
could get more warnings about dead code/data that way.

I could have written -Os or -O3, but some sources say the higher
levels may produce worse code due to too aggressive inlining etc, and
that you should measure before applying them (if performance is
important on that level).

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      04-03-2013
On Mar 30, 4:36*pm, Varun Tewari <(E-Mail Removed)> wrote:
> hello all,
>
> I get this doubt about this behavior of C.
>
> consider the following code.
>
> int a,b,d1,d2,diff;
>
> d1= &a;
> d2 = &b;
> diff = &a-&b;
> printf("\nDifference between address: %d", diff);
> diff = d1-d2;
> printf("\nDifference between address(stored in integers): %d", diff);
>
> ideally, both printf should result same output.
> but as expected diff = d1-d2 gives 4.
> but diff = &a-&b gives 1.
>
> Why so when C doesn't really support operator overloading.



what compiler successfully compiles this code?
 
Reply With Quote
 
Nick Keighley
Guest
Posts: n/a
 
      04-03-2013
On Apr 1, 6:31*pm, Varun Tewari <(E-Mail Removed)> wrote:
> Thnx Everyone.
>
> For me my doubts are cleared, and for those who think it wasn't a doubt but a question, yes my questions are well answered.
>
>



 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      04-03-2013
Nick Keighley <(E-Mail Removed)> writes:
> On Mar 30, 4:36*pm, Varun Tewari <(E-Mail Removed)> wrote:
>> I get this doubt about this behavior of C.
>>
>> consider the following code.
>>
>> int a,b,d1,d2,diff;
>>
>> d1= &a;
>> d2 = &b;
>> diff = &a-&b;
>> printf("\nDifference between address: %d", diff);
>> diff = d1-d2;
>> printf("\nDifference between address(stored in integers): %d", diff);
>>
>> ideally, both printf should result same output.
>> but as expected diff = d1-d2 gives 4.
>> but diff = &a-&b gives 1.
>>
>> Why so when C doesn't really support operator overloading.

>
>
> what compiler successfully compiles this code?


gcc does, once you add the obvious boilerplate.

It "successfully" compiles it in the sense that it generates an
executable that actually prints something. It does produce the required
diagnostics, but they're merely warnings. (The "-pedantic-errors"
option makes them fatal errors.)

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pointers, pointers, pointers... cerr C Programming 12 04-07-2011 11:17 PM
Difference between function pointers ram kishore C Programming 8 07-27-2008 04:02 PM
[pointers and arrays]: The difference between an array name and a pointer iamchiaweilin@gmail.com C Programming 7 10-02-2006 11:03 PM
Difference between bin and obj directories and difference between project references and dll references jakk ASP .Net 4 03-22-2005 09:23 PM
Why do so few people know the difference between arrays and pointers. Me C Programming 79 06-18-2004 12:35 PM



Advertisments