Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Function factories

Reply
Thread Tools

Function factories

 
 
James Kuyper
Guest
Posts: n/a
 
      08-23-2012
On 08/23/2012 01:02 PM, Chicken McNuggets wrote:
> On 23/08/2012 16:13, James Kuyper wrote:
>> On 08/23/2012 08:27 AM, Chicken McNuggets wrote:
>>> On 22/08/2012 16:05, James Kuyper wrote:
>>>
>>>>
>>>> However, I think that compile() looks horribly type-unsafe.
>>>>
>>>
>>> Type safety in C? That's a novel concept .

>>
>> Is it? Try compiling the following code:
>>
>> int main(void)
>> {
>> double d;
>> int *pi = &d;
>> return 0;
>> }
>>

>
> Yes. It compiles with a warning as expected. Not a great example of type
> safety.


It's a lot better than it would be if no warning were mandated. An
implementation is free to reject such code - whether or not it actually
does so is a matter of QoI, outside the scope of the standard.

> This code on the other hand compiles with no warnings:
>
> #include <stdlib.h>
>
> int main(void)
> {
> int *ptr = (int*) malloc(sizeof(long));
> *ptr = 10;
> short blah = *ptr;
> free(ptr);
> exit(EXIT_SUCCESS);
> }
>
> so please explain how C is a type safe language?


Type safety is not an absolute yes or no issue. Some languages have more
type safety than others. C has static type checking - in many different
contexts, a diagnostic is mandatory if different types are not
compatible. Implicit conversions are often safe conversions, the most
dangerous type conversions are required to be explicit (except those
pointer conversions which can be done using void* as an intermediate
type). There's plenty of room for improvement in C's type safety, but
it's still a lot better than having no type checking, or deferring type
checking until run-time (both of which I've seen in other languages).

> The fact that malloc() returns a void pointer that can be cast to any
> type destroys any type safety C may have.


No, it doesn't. It just adds another type-unsafe mechanism to a language
that has only a moderate amount of type safety without it.

lcc-win32's compile() looks to me like it compromises type safety much
more than malloc() does, which is what prompted my original comment. A
pointer to a function that might point have the wrong function type
seems much more serious to me than a pointer to an object that might
have the wrong object type; there's a larger variety of ways you can
have a mis-match, and a correspondingly larger number of different
failure modes available. It's not good, either way.

 
Reply With Quote
 
 
 
 
jacob navia
Guest
Posts: n/a
 
      08-23-2012
Le 23/08/12 19:35, James Kuyper a écrit :
> lcc-win32's compile() looks to me like it compromises type safety much
> more than malloc() does, which is what prompted my original comment. A
> pointer to a function that might point have the wrong function type
> seems much more serious to me than a pointer to an object that might
> have the wrong object type; there's a larger variety of ways you can
> have a mis-match, and a correspondingly larger number of different
> failure modes available. It's not good, either way.


But how can "compile()" know what type of function you are going to define?

There is absolutely NO WAY to change this fact. But of course if you
have one solution please let me know...

 
Reply With Quote
 
 
 
 
Melzzzzz
Guest
Posts: n/a
 
      08-23-2012
On Thu, 23 Aug 2012 11:13:54 -0400
James Kuyper <(E-Mail Removed)> wrote:

> int main(void)
> {
> double d;
> int *pi = &d;
> return 0;
> }

gcc by default compiles just fine, but issues warning
g++ gives error and that I don;t like ...


--
drwx------ 2 bmaxa bmaxa 4096 Aug 23 21:19 .

 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      08-23-2012
On 08/23/2012 03:21 PM, Melzzzzz wrote:
> On Thu, 23 Aug 2012 11:13:54 -0400
> James Kuyper <(E-Mail Removed)> wrote:
>
>> int main(void)
>> {
>> double d;
>> int *pi = &d;
>> return 0;
>> }

> gcc by default compiles just fine, but issues warning
> g++ gives error and that I don;t like ...


Personally, I like it when a compiler lets me know I've written
dangerously bad code. Why do you feel differently?

 
Reply With Quote
 
Melzzzzz
Guest
Posts: n/a
 
      08-23-2012
On Thu, 23 Aug 2012 15:36:00 -0400
James Kuyper <(E-Mail Removed)> wrote:

> On 08/23/2012 03:21 PM, Melzzzzz wrote:
> > On Thu, 23 Aug 2012 11:13:54 -0400
> > James Kuyper <(E-Mail Removed)> wrote:
> >
> >> int main(void)
> >> {
> >> double d;
> >> int *pi = &d;
> >> return 0;
> >> }

> > gcc by default compiles just fine, but issues warning
> > g++ gives error and that I don;t like ...

>
> Personally, I like it when a compiler lets me know I've written
> dangerously bad code. Why do you feel differently?
>


I wasn't clear. c++ issues error and that I don;t like,
while behavior of C compiler is just fine IMO


--
drwx------ 2 bmaxa bmaxa 4096 Aug 23 22:07 .

 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      08-23-2012
On 08/23/2012 04:09 PM, Melzzzzz wrote:
> On Thu, 23 Aug 2012 15:36:00 -0400
> James Kuyper <(E-Mail Removed)> wrote:
>
>> On 08/23/2012 03:21 PM, Melzzzzz wrote:
>>> On Thu, 23 Aug 2012 11:13:54 -0400
>>> James Kuyper <(E-Mail Removed)> wrote:
>>>
>>>> int main(void)
>>>> {
>>>> double d;
>>>> int *pi = &d;
>>>> return 0;
>>>> }
>>> gcc by default compiles just fine, but issues warning
>>> g++ gives error and that I don;t like ...

>>
>> Personally, I like it when a compiler lets me know I've written
>> dangerously bad code. Why do you feel differently?
>>

>
> I wasn't clear. c++ issues error and that I don;t like,
> while behavior of C compiler is just fine IMO


No, you were quite clear, but perhaps my response wasn't. It seems to me
that treating such code as an error is entirely appropriate; a warning
seems inadequate. Why do you feel differently?

If you actually have a legitimate need to do the conversion, and know
something implementation-specific that makes is safer than it is in the
general case, make those facts explicit by using a cast (in C) or a
reinterpret_cast<> (in C++). Requiring something as clumsy and as easily
searched for as reinterpret_cast<> in order to perform such a dangerous
conversion also strikes me as a good idea.


 
Reply With Quote
 
Melzzzzz
Guest
Posts: n/a
 
      08-23-2012
On Thu, 23 Aug 2012 16:20:55 -0400
James Kuyper <(E-Mail Removed)> wrote:

> On 08/23/2012 04:09 PM, Melzzzzz wrote:
> > On Thu, 23 Aug 2012 15:36:00 -0400
> > James Kuyper <(E-Mail Removed)> wrote:
> >
> >> On 08/23/2012 03:21 PM, Melzzzzz wrote:
> >>> On Thu, 23 Aug 2012 11:13:54 -0400
> >>> James Kuyper <(E-Mail Removed)> wrote:
> >>>
> >>>> int main(void)
> >>>> {
> >>>> double d;
> >>>> int *pi = &d;
> >>>> return 0;
> >>>> }
> >>> gcc by default compiles just fine, but issues warning
> >>> g++ gives error and that I don;t like ...
> >>
> >> Personally, I like it when a compiler lets me know I've written
> >> dangerously bad code. Why do you feel differently?
> >>

> >
> > I wasn't clear. c++ issues error and that I don;t like,
> > while behavior of C compiler is just fine IMO

>
> No, you were quite clear, but perhaps my response wasn't. It seems to
> me that treating such code as an error is entirely appropriate; a
> warning seems inadequate. Why do you feel differently?


It seems that reduces number of casts in code. Warning is enough
if it is accidental error.

>
> If you actually have a legitimate need to do the conversion, and know
> something implementation-specific that makes is safer than it is in
> the general case, make those facts explicit by using a cast (in C) or
> a reinterpret_cast<> (in C++). Requiring something as clumsy and as
> easily searched for as reinterpret_cast<> in order to perform such a
> dangerous conversion also strikes me as a good idea.


Well compiler warnings are enough aren't they? Cast just masks warning
and makes compiler happy which is not good thing.
Well if you have to search trough code to find that one error is much
more difficult rather then just check compiler warning.
I don;t like to shut up compiler warnings with casts and that's
why C's approach is better.


 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      08-23-2012
On 08/23/2012 04:33 PM, Melzzzzz wrote:
> On Thu, 23 Aug 2012 16:20:55 -0400
> James Kuyper <(E-Mail Removed)> wrote:
>
>> On 08/23/2012 04:09 PM, Melzzzzz wrote:
>>> On Thu, 23 Aug 2012 15:36:00 -0400
>>> James Kuyper <(E-Mail Removed)> wrote:
>>>
>>>> On 08/23/2012 03:21 PM, Melzzzzz wrote:
>>>>> On Thu, 23 Aug 2012 11:13:54 -0400
>>>>> James Kuyper <(E-Mail Removed)> wrote:
>>>>>
>>>>>> int main(void)
>>>>>> {
>>>>>> double d;
>>>>>> int *pi = &d;
>>>>>> return 0;
>>>>>> }
>>>>> gcc by default compiles just fine, but issues warning
>>>>> g++ gives error and that I don;t like ...
>>>>
>>>> Personally, I like it when a compiler lets me know I've written
>>>> dangerously bad code. Why do you feel differently?
>>>>
>>>
>>> I wasn't clear. c++ issues error and that I don;t like,
>>> while behavior of C compiler is just fine IMO

>>
>> No, you were quite clear, but perhaps my response wasn't. It seems to
>> me that treating such code as an error is entirely appropriate; a
>> warning seems inadequate. Why do you feel differently?

>
> It seems that reduces number of casts in code. Warning is enough
> if it is accidental error.


As opposed to a deliberate error?
I have to disagree with you about whether reducing the number of casts
is a good idea. See below.

>> If you actually have a legitimate need to do the conversion, and know
>> something implementation-specific that makes is safer than it is in
>> the general case, make those facts explicit by using a cast (in C) or
>> a reinterpret_cast<> (in C++). Requiring something as clumsy and as
>> easily searched for as reinterpret_cast<> in order to perform such a
>> dangerous conversion also strikes me as a good idea.

>
> Well compiler warnings are enough aren't they? Cast just masks warning
> and makes compiler happy which is not good thing.


No, in the unlikely event that you have legitimate reason to write such
code, a cast explicitly requests that the conversion should occur (and
in some cases makes a conversion occur that could not occur implicitly).
It documents the developer's assertion that there is a legitimate reason
for performing what is ordinarily a rather dangerous operation. Code
that is correctly written to do what it does should not generate
warnings, even if it does use dangerous methods to get there. The danger
should be marked by the presence of the cast, not by generation of
warning messages. Producing warning messages from correct code
desensitizes developers to warning messages associated with incorrect
code. The cast should be easy to notice and search for, which is one
reason why reinterpret-cast<> is better than a C-style cast.

> Well if you have to search trough code to find that one error is much
> more difficult rather then just check compiler warning.


That doesn't explain why you think a compiler error is worse than a
compiler warning. If the error message is written properly, both will
give you the location of the problem, so there's no need to go searching.

> I don;t like to shut up compiler warnings with casts and that's
> why C's approach is better.


C doesn't make any different approach than C++ in this case; the
construct is equally an error in both languages, and neither language
specifies what an implementation should do about it, beyond issuing the
mandatory diagnostic. It's the compiler that's decided to handle these
two languages differently, not the language specifications.

Note that, given C's anti-aliasing rules, in the unlikely event that you
do have a legitimate reason to write code like that, it would be better
to use code like this:

union { double d, int i} u;
int *pi = &u.i;

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-23-2012
Melzzzzz <(E-Mail Removed)> writes:
[...]
> Well compiler warnings are enough aren't they? Cast just masks warning
> and makes compiler happy which is not good thing.
> Well if you have to search trough code to find that one error is much
> more difficult rather then just check compiler warning.
> I don;t like to shut up compiler warnings with casts and that's
> why C's approach is better.


The code in question was:

double d;
int *pi = &d;

and the question is whether a compiler should reject it with an error
message or accept it with a mere warning.

Personally, I would never deliberately write that. As far as the C
standard is concerned, it's a constraint violation, requiring a
diagnostic from any conforming compiler. If a compiler issues a warning
and continues to compile the code, it might seem reasonable to assume
that it will generate a conversion from `double*` to `int*` -- but in
fact the language standard does not say or imply that that's what will
happen. The behavior is undefined; a compiler could legally generate
code that sets `pi` to a null pointer, for example.

Whereas if I *want* to do that conversion, there's a perfectly valid way
to do it that likely won't result in a warning:

double d;
int *pi = (int*)&d;

A problem I have with gcc is that it doesn't clearly distinguish between
warnings about constraint violations, like the above, and warnings about
legal but questionable code, such as writing `if (x = 42)` rather than
`if (x == 42)`. Again, this doesn't violate the C standard; I just
personally find it annoying.

That's just my opinion (that all syntax errors and constraint violations
should be treated as fatal errors, not as warnings -- or at least that
there should be an option that works that way). What's yours? Which
errors do you think should be fatal, and which should merely trigger a
warning?

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Melzzzzz
Guest
Posts: n/a
 
      08-23-2012
On Thu, 23 Aug 2012 14:51:59 -0700
Keith Thompson <(E-Mail Removed)> wrote:

> Melzzzzz <(E-Mail Removed)> writes:
> [...]
> > Well compiler warnings are enough aren't they? Cast just masks
> > warning and makes compiler happy which is not good thing.
> > Well if you have to search trough code to find that one error is
> > much more difficult rather then just check compiler warning.
> > I don;t like to shut up compiler warnings with casts and that's
> > why C's approach is better.

>
> The code in question was:
>
> double d;
> int *pi = &d;
>
> and the question is whether a compiler should reject it with an error
> message or accept it with a mere warning.
>
> Personally, I would never deliberately write that. As far as the C
> standard is concerned, it's a constraint violation, requiring a
> diagnostic from any conforming compiler. If a compiler issues a
> warning and continues to compile the code, it might seem reasonable
> to assume that it will generate a conversion from `double*` to `int*`
> -- but in fact the language standard does not say or imply that
> that's what will happen. The behavior is undefined; a compiler could
> legally generate code that sets `pi` to a null pointer, for example.


I didn't knew that this is undefined behavior.

>
> Whereas if I *want* to do that conversion, there's a perfectly valid
> way to do it that likely won't result in a warning:
>
> double d;
> int *pi = (int*)&d;
>


Problem is that we wont get warning in this case IMO.

> A problem I have with gcc is that it doesn't clearly distinguish
> between warnings about constraint violations, like the above, and
> warnings about legal but questionable code, such as writing `if (x =
> 42)` rather than `if (x == 42)`. Again, this doesn't violate the C
> standard; I just personally find it annoying.
>
> That's just my opinion (that all syntax errors and constraint
> violations should be treated as fatal errors, not as warnings -- or
> at least that there should be an option that works that way). What's
> yours? Which errors do you think should be fatal, and which should
> merely trigger a warning?


I don't think that converting one pointer type to other is error.
It seems to me that in spirit of C it should be allowed as it is.
It should issue error if types are incompatible, say pointer to int
has less bytes than pointer to double.
Problem is that if code that uses such conversions will work at all.
Say copying data as int / reading as double.
It might work in one case and might not in other.
It would be very difficult to find out bug (wrong result etc) without
compiler warning IMO.


 
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
function factories and argument names Chadrik Python 0 06-21-2008 12:07 AM
Design Patterns: Factories VS Abstract Factories tim@nocomment.com Java 1 10-02-2006 08:35 PM
JSF: no factories configured for this application Timo Nentwig Java 0 04-27-2004 10:34 AM
JSP: Beans from factories? Kai Grossjohann Java 2 12-17-2003 08:04 PM
overridding factories. Roedy Green Java 0 08-24-2003 08:55 PM



Advertisments