Velocity Reviews - Computer Hardware Reviews

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

Reply
Thread Tools

Function factories

 
 
jacob navia
Guest
Posts: n/a
 
      08-23-2012
Le 22/08/12 17:05, James Kuyper a écrit :
> On 08/22/2012 10:40 AM, tom st denis wrote:
>> On Aug 22, 6:32 am, jacob navia <ja...@spamsink.net> wrote:

> ...
>>> If you have the JIT of lcc-win you write:
>>>
>>> typedef int (*foo)(int);
>>>
>>> foo adder_factory(int value)
>>> {
>>> foo fnPtr;
>>> char buf[512];
>>>
>>> sprintf(buf,"int fn(int a) { return a + %d;}",value);
>>> fnPtr = (foo)compile(buf);
>>> return fnPtr;

>>
>> You could accomplish similiar [though more longwinded] via compiling
>> code and using dlopen() to load it into your process space.

>
> The intent was for the definition of the adder to be contained inside
> the definition of adder_factory().
>
>> Both of which are completely OT for this group though.
>>
>> BTW: your code doesn't seem to do any sort of error checking. What if
>> compile() fails?

>
> From the way it's used, it would appear to return a pointer.


By convention it returns a pointer to the first function it finds.
This is highly dependent on the application and customer setup.

Some customers want to have a "main" function that starts the thing.
In that case the JIT will return a pointer to that function. Others
will put the main function at the start of the file and the Jit returns
a function to the first function it compiles.

In case of error (syntax error, no more memory, whatever catastrophe
occurs), it returns NULL. Diagnostics are printed in stderr, whatever
that is. In most applications stderr is a pipe connected to some
file.

Obviously in most applications the code buffer is machine generated.
It could be however that it is used as a C interpreter.

The resulting code is dynamically linked to the running program. There
is no preprocessor.

> If
> compile() fails, it might return a null pointer, in which case
> adder_factory() will also return a null pointer, leaving it for the
> caller to decide what to do about it. That's a perfectly reasonable way
> of passing on the information that the call failed.
>
> However, I think that compile() looks horribly type-unsafe.
>


In a sense yes, since it can return a pointer to ANY kind of function
by definition... It is up to you to cast the result pointer into
the right stuff. I do not see how to improve that without destroying
the generality of the program.

But we are used to it. fread() will read ANY kind of stuff into its
buffer, it is up to you to interpret the data correctly.
 
Reply With Quote
 
 
 
 
Chicken McNuggets
Guest
Posts: n/a
 
      08-23-2012
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 .
 
Reply With Quote
 
 
 
 
Heinrich Wolf
Guest
Posts: n/a
 
      08-23-2012

"James Kuyper" <> schrieb im Newsbeitrag
news:...
....
>> 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;
> }


It compiles! On both Turbo C 2.0 and Borland C++Builder 5.

There are just 2 warnings:

Warning J:\C\TURBO2\NONAME.C 4: Suspicious pointer conversion in function
main
Warning J:\C\TURBO2\NONAME.C 6: 'pi' is assigned a value which is never used
in function main

Pascal is said to be more type safe. But I am astonished: Delphi 5 does not
issue a warning at all, just a hint:

program TypeSafe;
{$APPTYPE CONSOLE}

var d : double;
pi : ^integer;
begin
pi := @d;
exitcode := 0;
end.

[Hint] TypeSafe.dpr(7): 'pi' is assigned a value which is never used



Heiner

 
Reply With Quote
 
Anand Hariharan
Guest
Posts: n/a
 
      08-23-2012
On Aug 23, 10:13*am, James Kuyper <jameskuy...@verizon.net> 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;
> }


One additional line (that doesn't involve any casts) is sufficient -

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

$ gcc -W -Wall -ansi -pedantic foo.c
foo.c: In function ‘main’:
foo.c:6:10: warning: unused variable ‘pi’


 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      08-23-2012
On 08/23/2012 12:18 PM, Heinrich Wolf wrote:
>
> "James Kuyper" <> schrieb im Newsbeitrag
> news:...
> ...
>>> 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;
>> }

>
> It compiles! On both Turbo C 2.0 and Borland C++Builder 5.
>
> There are just 2 warnings:
>
> Warning J:\C\TURBO2\NONAME.C 4: Suspicious pointer conversion in function
> main
> Warning J:\C\TURBO2\NONAME.C 6: 'pi' is assigned a value which is never used
> in function main


The most that the C standard ever requires an implementation to do when
processing a program that has any kind of defect is to produce at least
one diagnostic message, contents unspecified; whether it then continues
to generate an executable is entirely up to the implementation. This is
one such case, a constraint violation (6.5.16.1p1). Any implementation
for which this program fails to produce at least one diagnostic is
non-conforming.


 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      08-23-2012
On 08/23/2012 12:18 PM, Heinrich Wolf wrote:
>
> "James Kuyper" <> schrieb im Newsbeitrag
> news:...
> ...
>>> 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;
>> }

>
> It compiles! On both Turbo C 2.0 and Borland C++Builder 5.
>
> There are just 2 warnings:
>
> Warning J:\C\TURBO2\NONAME.C 4: Suspicious pointer conversion in function
> main
> Warning J:\C\TURBO2\NONAME.C 6: 'pi' is assigned a value which is never used
> in function main


The most that the C standard ever requires an implementation to do when
processing a program that has any kind of defect is to produce at least
one diagnostic message, contents unspecified; whether it then continues
to generate an executable is entirely up to the implementation. This is
one such case, a constraint violation (6.5.16.1p1). Any implementation
for which this program fails to produce at least one diagnostic is
non-conforming.


 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      08-23-2012
Le 23/08/12 18:29, Anand Hariharan a écrit :
> On Aug 23, 10:13 am, James Kuyper <jameskuy...@verizon.net> 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;
>> }

>
> One additional line (that doesn't involve any casts) is sufficient -
>
> int main(void)
> {
> double d;
> void *pv = &d;
> int *pi = pv;
> return 0;
> }
>
> $ gcc -W -Wall -ansi -pedantic foo.c
> foo.c: In function ‘main’:
> foo.c:6:10: warning: unused variable ‘pi’
>
>


C allows you to interpret ANY part of memory as something else if you
(as you have shown) are careful to avoid the built-in barriers of the
language.

Interpreting doubles as integers is very useful if you want to test
some bits or manipulate some bits of the binary representation without
going through expensive floating point operations. The whole Sun math
library is built using this kind of code, and you can do that in C since
it is a language that doesn't IMPOSE anything to the programmer, like
C#, C++ or Cwhatever.


 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      08-23-2012
On 08/23/2012 12:29 PM, Anand Hariharan wrote:
> On Aug 23, 10:13 am, James Kuyper <jameskuy...@verizon.net> 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;
>> }

>
> One additional line (that doesn't involve any casts) is sufficient -
>
> int main(void)
> {
> double d;
> void *pv = &d;
> int *pi = pv;
> return 0;
> }


Sure, C's support of type safety is weak, and easily circumvented. But
it's not non-existent, as implied by Chicken's first comment above. I've
used several languages with substantially less type safety; mostly ones
where type mismatches are not detected until something blows up at run
time. I greatly prefer catching them at compile time (a concept which
doesn't even apply to some of those languages).

 
Reply With Quote
 
Chicken McNuggets
Guest
Posts: n/a
 
      08-23-2012
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.

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?

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

Try Haskell for a real type safe language.
 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      08-23-2012
Le 23/08/12 19:02, Chicken McNuggets a écrit :
> 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.
>
> 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?
>


Because you can assign a 64 bit integer into a short. If there is an
overflow the behavior is undefined but it can't be any overflow in your
example since 10 will fit into a short.

What is the problem?

> The fact that malloc() returns a void pointer that can be cast to any
> type destroys any type safety C may have.
>
> Try Haskell for a real type safe language.


OK
Lets suppose I have a double precision number and that I want to reset
the sign bit without doing any expensive floating point operations.

How do I do that in Haskell?
 
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