Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #24688 > unrolled thread

Function factories

Started byEdward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com>
First post2012-08-21 20:36 +0000
Last post2012-08-24 02:37 -0700
Articles 20 on this page of 43 — 17 participants

Back to article view | Back to comp.lang.c


Contents

  Function factories Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2012-08-21 20:36 +0000
    Re: Function factories Nobody <nobody@nowhere.com> - 2012-08-21 21:55 +0100
      Re: Function factories Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2012-08-22 16:36 +0000
        Re: Function factories James Kuyper <jameskuyper@verizon.net> - 2012-08-22 13:01 -0400
          Re: Function factories Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> - 2012-08-22 18:33 +0000
          Re: Function factories James Kuyper <jameskuyper@verizon.net> - 2012-08-22 22:26 -0400
    Re: Function factories David Brown <david@westcontrol.removethisbit.com> - 2012-08-22 08:34 +0200
      Re: Function factories Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-08-22 01:52 -0700
        Re: Function factories David Brown <david@westcontrol.removethisbit.com> - 2012-08-22 11:34 +0200
        Re: Function factories Gareth Owen <gwowen@gmail.com> - 2012-08-24 17:30 +0100
      Re: Function factories Gareth Owen <gwowen@gmail.com> - 2012-08-24 17:29 +0100
    Re: Function factories jacob navia <jacob@spamsink.net> - 2012-08-22 12:32 +0200
      Re: Function factories tom st denis <tom@iahu.ca> - 2012-08-22 07:40 -0700
        Re: Function factories James Kuyper <jameskuyper@verizon.net> - 2012-08-22 11:05 -0400
          Re: Function factories jacob navia <jacob@spamsink.net> - 2012-08-23 11:08 +0200
          Re: Function factories Chicken McNuggets <chicken@mcnuggets.com> - 2012-08-23 13:27 +0100
            Re: Function factories James Kuyper <jameskuyper@verizon.net> - 2012-08-23 11:13 -0400
              Re: Function factories "Heinrich Wolf" <invalid@invalid.invalid> - 2012-08-23 18:18 +0200
                Re: Function factories James Kuyper <jameskuyper@verizon.net> - 2012-08-23 12:40 -0400
              Re: Function factories Anand Hariharan <mailto.anand.hariharan@gmail.com> - 2012-08-23 09:29 -0700
                Re: Function factories jacob navia <jacob@spamsink.net> - 2012-08-23 18:44 +0200
                Re: Function factories James Kuyper <jameskuyper@verizon.net> - 2012-08-23 12:46 -0400
              Re: Function factories Chicken McNuggets <chicken@mcnuggets.com> - 2012-08-23 18:02 +0100
                Re: Function factories jacob navia <jacob@spamsink.net> - 2012-08-23 19:24 +0200
                  Re: Function factories eq mail <eq.mail.id@gmail.com> - 2012-08-23 18:07 -0700
                    Re: Function factories Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-08-23 21:30 -0400
                      Re: Function factories eq mail <eq.mail.id@gmail.com> - 2012-08-23 21:46 -0700
                Re: Function factories James Kuyper <jameskuyper@verizon.net> - 2012-08-23 13:35 -0400
                  Re: Function factories jacob navia <jacob@spamsink.net> - 2012-08-23 20:13 +0200
                Re: Function factories eq mail <eq.mail.id@gmail.com> - 2012-08-23 17:57 -0700
                Re: Function factories Andrew Cooper <amc96@cam.ac.uk> - 2012-08-25 02:35 +0100
              Re: Function factories Melzzzzz <mel@zzzzz.invalid> - 2012-08-23 21:21 +0200
                Re: Function factories James Kuyper <jameskuyper@verizon.net> - 2012-08-23 15:36 -0400
                  Re: Function factories Melzzzzz <mel@zzzzz.invalid> - 2012-08-23 22:09 +0200
                    Re: Function factories James Kuyper <jameskuyper@verizon.net> - 2012-08-23 16:20 -0400
                      Re: Function factories Melzzzzz <mel@zzzzz.com> - 2012-08-23 22:33 +0200
                        Re: Function factories James Kuyper <jameskuyper@verizon.net> - 2012-08-23 17:07 -0400
                        Re: Function factories Keith Thompson <kst-u@mib.org> - 2012-08-23 14:51 -0700
                          Re: Function factories Melzzzzz <mel@zzzzz.com> - 2012-08-24 00:09 +0200
                            Re: Function factories James Kuyper <jameskuyper@verizon.net> - 2012-08-23 19:01 -0400
                            Re: Function factories Keith Thompson <kst-u@mib.org> - 2012-08-23 16:31 -0700
                              Re: Function factories Melzzzzz <mel@zzzzz.com> - 2012-08-24 18:31 +0200
                        Re: Function factories Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-08-24 02:37 -0700

Page 1 of 3  [1] 2 3  Next page →


#24688 — Function factories

FromEdward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com>
Date2012-08-21 20:36 +0000
SubjectFunction factories
Message-ID<k10rgf$oep$1@speranza.aioe.org>
Hello

I want to make a factory that produces other functions according to a 
parameter.

The following code does not compile:

typedef int *(foo)(int);

foo adder_factory(int x)
{
  int f(int a)
  {
    return a + x;
  }
  return &f;
}

The idea is that adder_factor(42) should be a function that adds 42 to 
whatever it gets passed.

What's the right way of doing this in C? How can I get closures or 
something similar in C?

[toc] | [next] | [standalone]


#24689

FromNobody <nobody@nowhere.com>
Date2012-08-21 21:55 +0100
Message-ID<pan.2012.08.21.20.55.41.481000@nowhere.com>
In reply to#24688
On Tue, 21 Aug 2012 20:36:31 +0000, Edward Rutherford wrote:

> I want to make a factory that produces other functions according to a
> parameter.
> 
> The following code does not compile:
> 
> typedef int *(foo)(int);
> 
> foo adder_factory(int x)
> {
>   int f(int a)
>   {
>     return a + x;
>   }
>   return &f;
> }

C does not have inner functions or closures.

> The idea is that adder_factor(42) should be a function that adds 42 to
> whatever it gets passed.
> 
> What's the right way of doing this in C? How can I get closures or
> something similar in C?

typedef struct foo {
    int (*func)(const struct foo *, int);
    int param;
} *foo;

static int adder(const struct foo *closure, int x) {
    return closure->param + x;
}

foo adder_factory(int x)
{
    foo p = malloc(sizeof(*p));
    p->func = adder;
    p->param = x;
    return p;
}

#define call_foo(f, x) ((f)->func((f), (x))

[toc] | [prev] | [next] | [standalone]


#24704

FromEdward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com>
Date2012-08-22 16:36 +0000
Message-ID<k131pp$8gi$1@speranza.aioe.org>
In reply to#24689
Nobody wrote:
> On Tue, 21 Aug 2012 20:36:31 +0000, Edward Rutherford wrote:
> 
>> I want to make a factory that produces other functions according to a
>> parameter.
>> 
>> The following code does not compile:
>> 
>> typedef int *(foo)(int);
>> 
>> foo adder_factory(int x)
>> {
>>   int f(int a)
>>   {
>>     return a + x;
>>   }
>>   return &f;
>> }
> 
> C does not have inner functions or closures.
> 
>> The idea is that adder_factor(42) should be a function that adds 42 to
>> whatever it gets passed.
>> 
>> What's the right way of doing this in C? How can I get closures or
>> something similar in C?
> 
> typedef struct foo {
>     int (*func)(const struct foo *, int); int param;
> } *foo;
> 
> static int adder(const struct foo *closure, int x) {
>     return closure->param + x;
> }
> 
> foo adder_factory(int x)
> {
>     foo p = malloc(sizeof(*p));
>     p->func = adder;
>     p->param = x;
>     return p;
> }
> 
> #define call_foo(f, x) ((f)->func((f), (x))

Thanks for the suggestion. Unfortunately I need an actual function, not a 
macro, to be able to pass as a comparator function to qsort.

Guess I just have to communicate what I need through a global variable? 
It would be nice if qsort took an extra "void *data" parameter, like 
functions in Glib (where it's called a gpointer of course)...

[toc] | [prev] | [next] | [standalone]


#24705

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-08-22 13:01 -0400
Message-ID<50351056.10908@verizon.net>
In reply to#24704
On 08/22/2012 12:36 PM, Edward Rutherford wrote:
> Nobody wrote:
>> On Tue, 21 Aug 2012 20:36:31 +0000, Edward Rutherford wrote:
...
>>> The idea is that adder_factor(42) should be a function that adds 42 to
>>> whatever it gets passed.
>>>
>>> What's the right way of doing this in C? How can I get closures or
>>> something similar in C?
>>
>> typedef struct foo {
>>     int (*func)(const struct foo *, int); int param;
>> } *foo;
>>
>> static int adder(const struct foo *closure, int x) {
>>     return closure->param + x;
>> }
>>
>> foo adder_factory(int x)
>> {
>>     foo p = malloc(sizeof(*p));
>>     p->func = adder;
>>     p->param = x;
>>     return p;
>> }
>>
>> #define call_foo(f, x) ((f)->func((f), (x))
> 
> Thanks for the suggestion. Unfortunately I need an actual function, not a 
> macro, to be able to pass as a comparator function to qsort.
> 
> Guess I just have to communicate what I need through a global variable?

That's one alternative. However, you can avoid creating a global, with
all of the attendant problems. When used correctly, qsort() never calls
the comparison function with null pointers. You can take advantage of
that fact by making x a static variable local to the comparison
function, and if the first argument to that function is a null pointer,
interpret the second argument as a pointer to a new value for x.

> It would be nice if qsort took an extra "void *data" parameter, like 
> functions in Glib (where it's called a gpointer of course)...

Yes. It's a well-known problem with all of the original C standard
library's callback functions. I think C11 has introduced some new
callbacks, but I haven't had time to learn much about them.


[toc] | [prev] | [next] | [standalone]


#24712

FromEdward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com>
Date2012-08-22 18:33 +0000
Message-ID<k138lk$q15$1@speranza.aioe.org>
In reply to#24705
James Kuyper wrote:

> On 08/22/2012 12:36 PM, Edward Rutherford wrote:
>> Nobody wrote:
>>> On Tue, 21 Aug 2012 20:36:31 +0000, Edward Rutherford wrote:
> ...
>>>> The idea is that adder_factor(42) should be a function that adds 42
>>>> to whatever it gets passed.
>>>>
>>>> What's the right way of doing this in C? How can I get closures or
>>>> something similar in C?
>>>
>>> typedef struct foo {
>>>     int (*func)(const struct foo *, int); int param;
>>> } *foo;
>>>
>>> static int adder(const struct foo *closure, int x) {
>>>     return closure->param + x;
>>> }
>>>
>>> foo adder_factory(int x)
>>> {
>>>     foo p = malloc(sizeof(*p));
>>>     p->func = adder;
>>>     p->param = x;
>>>     return p;
>>> }
>>>
>>> #define call_foo(f, x) ((f)->func((f), (x))
>> 
>> Thanks for the suggestion. Unfortunately I need an actual function, not
>> a macro, to be able to pass as a comparator function to qsort.
>> 
>> Guess I just have to communicate what I need through a global variable?
> 
> That's one alternative. However, you can avoid creating a global, with
> all of the attendant problems. When used correctly, qsort() never calls
> the comparison function with null pointers. You can take advantage of
> that fact by making x a static variable local to the comparison
> function, and if the first argument to that function is a null pointer,
> interpret the second argument as a pointer to a new value for x.

That is very clever.

It does feel like a little bit of a hack to me, and I'd probably want to 
comment what was going on quite carefully.

It also has the downside of introducing an extra branch instruction 
(check against NULL) in a function that could be called many many times 
in a sort.

Still, ingenious! Thanks.

[toc] | [prev] | [next] | [standalone]


#24736

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-08-22 22:26 -0400
Message-ID<k144d6$kk7$1@dont-email.me>
In reply to#24705
On 08/22/2012 01:01 PM, James Kuyper wrote:
> On 08/22/2012 12:36 PM, Edward Rutherford wrote:
...
>> It would be nice if qsort took an extra "void *data" parameter, like 
>> functions in Glib (where it's called a gpointer of course)...
> 
> Yes. It's a well-known problem with all of the original C standard
> library's callback functions. I think C11 has introduced some new
> callbacks, but I haven't had time to learn much about them.

The new callback function is the one passed to
set_constraint_handler_s(). You cannot pass set_constraint_handler_s() a
corresponding  void*data to be passed to the constraint handler when it
is called, so it looks like the committee has opted for consistency with
previous callback functions, rather than more flexible functionality.

constraint_handler_t functions take a second argument that is a void*,
but it is either null or points at an implementation-defined object,
which means that portable code can't do anything more useful with that
pointer than reporting whether or not it's null (which isn't
spectacularly useful).
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#24695

FromDavid Brown <david@westcontrol.removethisbit.com>
Date2012-08-22 08:34 +0200
Message-ID<EJqdnfZqgq8B4KnNnZ2dnUVZ8oqdnZ2d@lyse.net>
In reply to#24688
On 21/08/2012 22:36, Edward Rutherford wrote:
> Hello
>
> I want to make a factory that produces other functions according to a
> parameter.
>
> The following code does not compile:
>
> typedef int *(foo)(int);
>
> foo adder_factory(int x)
> {
>    int f(int a)
>    {
>      return a + x;
>    }
>    return &f;
> }
>
> The idea is that adder_factor(42) should be a function that adds 42 to
> whatever it gets passed.
>
> What's the right way of doing this in C? How can I get closures or
> something similar in C?
>

You can't.

You can get sort-of simulated closures in complicated and verbose ways, 
but there is no good way to do it.  gcc supports nested functions as an 
extension to C, but that won't give you closures like this.

If you want to stick close to C, then C++11 supports lambda functions 
and closures.

If you want to write code that makes strong use of closures in the 
style, then use a programming language that supports it.  The latest C++ 
standard will get you the basics, but if you want to write code in a 
more functional programming style, there are much better languages to 
work with (ocaml, python, haskell, etc.)

[toc] | [prev] | [next] | [standalone]


#24697

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2012-08-22 01:52 -0700
Message-ID<158866c9-ecb4-4242-b62e-ce217fbd16d9@q17g2000yqh.googlegroups.com>
In reply to#24695
On Aug 22, 7:34 am, David Brown <da...@westcontrol.removethisbit.com>
wrote:
> On 21/08/2012 22:36, Edward Rutherford wrote:
>
>
>
>
>
> > Hello
>
> > I want to make a factory that produces other functions according to a
> > parameter.
>
> > The following code does not compile:
>
> > typedef int *(foo)(int);
>
> > foo adder_factory(int x)
> > {
> >    int f(int a)
> >    {
> >      return a + x;
> >    }
> >    return &f;
> > }
>
> > The idea is that adder_factor(42) should be a function that adds 42 to
> > whatever it gets passed.
>
> > What's the right way of doing this in C? How can I get closures or
> > something similar in C?
>
> You can't.
>
> You can get sort-of simulated closures in complicated and verbose ways,
> but there is no good way to do it.  gcc supports nested functions as an
> extension to C, but that won't give you closures like this.
>
> If you want to stick close to C, then C++11 supports lambda functions
> and closures.
>
> If you want to write code that makes strong use of closures in the
> style, then use a programming language that supports it.  The latest C++
> standard will get you the basics, but if you want to write code in a
> more functional programming style, there are much better languages to
> work with (ocaml, python, haskell, etc.)

scheme

(and does Python have particularly good support for functional
programming?)

[toc] | [prev] | [next] | [standalone]


#24698

FromDavid Brown <david@westcontrol.removethisbit.com>
Date2012-08-22 11:34 +0200
Message-ID<5034A7BB.10006@westcontrol.removethisbit.com>
In reply to#24697
On 22/08/2012 10:52, Nick Keighley wrote:
> On Aug 22, 7:34 am, David Brown <da...@westcontrol.removethisbit.com>
> wrote:
>> On 21/08/2012 22:36, Edward Rutherford wrote:
>>
>>
>>
>>
>>
>>> Hello
>>
>>> I want to make a factory that produces other functions according to a
>>> parameter.
>>
>>> The following code does not compile:
>>
>>> typedef int *(foo)(int);
>>
>>> foo adder_factory(int x)
>>> {
>>>     int f(int a)
>>>     {
>>>       return a + x;
>>>     }
>>>     return &f;
>>> }
>>
>>> The idea is that adder_factor(42) should be a function that adds 42 to
>>> whatever it gets passed.
>>
>>> What's the right way of doing this in C? How can I get closures or
>>> something similar in C?
>>
>> You can't.
>>
>> You can get sort-of simulated closures in complicated and verbose ways,
>> but there is no good way to do it.  gcc supports nested functions as an
>> extension to C, but that won't give you closures like this.
>>
>> If you want to stick close to C, then C++11 supports lambda functions
>> and closures.
>>
>> If you want to write code that makes strong use of closures in the
>> style, then use a programming language that supports it.  The latest C++
>> standard will get you the basics, but if you want to write code in a
>> more functional programming style, there are much better languages to
>> work with (ocaml, python, haskell, etc.)
>
> scheme
>
> (and does Python have particularly good support for functional
> programming?)
>

Python has quite good support for functional programming styles, though 
it is mainly a procedural / object oriented language.  You do get 
closures, list comprehension, functions as first-class objects, and a 
sort of lazy evaluation (through iterators).  It does not have pattern 
matching in the way languages like Haskell have, which would have been nice.

[toc] | [prev] | [next] | [standalone]


#24857

FromGareth Owen <gwowen@gmail.com>
Date2012-08-24 17:30 +0100
Message-ID<87k3wojlro.fsf@gmail.com>
In reply to#24697
Nick Keighley <nick_keighley_nospam@hotmail.com> writes:

> scheme
>
> (and does Python have particularly good support for functional
> programming?)

Is the second line an aside, or sample Scheme code?

[toc] | [prev] | [next] | [standalone]


#24856

FromGareth Owen <gwowen@gmail.com>
Date2012-08-24 17:29 +0100
Message-ID<87obm0jlsl.fsf@gmail.com>
In reply to#24695
David Brown <david@westcontrol.removethisbit.com> writes:

> If you want to stick close to C, then C++11 supports lambda functions
> and closures.

And all C++ supports functors (i.e. classes with operator()) which will
certainly do the job in many use-cases...

[toc] | [prev] | [next] | [standalone]


#24700

Fromjacob navia <jacob@spamsink.net>
Date2012-08-22 12:32 +0200
Message-ID<k12cgb$k4g$1@speranza.aioe.org>
In reply to#24688
Le 21/08/12 22:36, Edward Rutherford a écrit :
> Hello
>
> I want to make a factory that produces other functions according to a
> parameter.
>
> The following code does not compile:
>
> typedef int *(foo)(int);
>
> foo adder_factory(int x)
> {
>    int f(int a)
>    {
>      return a + x;
>    }
>    return &f;
> }
>
> The idea is that adder_factor(42) should be a function that adds 42 to
> whatever it gets passed.
>
> What's the right way of doing this in C? How can I get closures or
> something similar in C?
>

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;
}

[toc] | [prev] | [next] | [standalone]


#24702

Fromtom st denis <tom@iahu.ca>
Date2012-08-22 07:40 -0700
Message-ID<58c40758-f7d1-4272-b4ce-ed5c185bc56b@p5g2000vbl.googlegroups.com>
In reply to#24700
On Aug 22, 6:32 am, jacob navia <ja...@spamsink.net> wrote:
> Le 21/08/12 22:36, Edward Rutherford a écrit :
>
>
>
>
>
>
>
>
>
> > Hello
>
> > I want to make a factory that produces other functions according to a
> > parameter.
>
> > The following code does not compile:
>
> > typedef int *(foo)(int);
>
> > foo adder_factory(int x)
> > {
> >    int f(int a)
> >    {
> >      return a + x;
> >    }
> >    return &f;
> > }
>
> > The idea is that adder_factor(42) should be a function that adds 42 to
> > whatever it gets passed.
>
> > What's the right way of doing this in C? How can I get closures or
> > something similar in C?
>
> 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.

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?

Tom

[toc] | [prev] | [next] | [standalone]


#24703

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-08-22 11:05 -0400
Message-ID<5034F54B.9050403@verizon.net>
In reply to#24702
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. 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.

[toc] | [prev] | [next] | [standalone]


#24744

Fromjacob navia <jacob@spamsink.net>
Date2012-08-23 11:08 +0200
Message-ID<k14rtn$3rg$1@speranza.aioe.org>
In reply to#24703
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.

[toc] | [prev] | [next] | [standalone]


#24747

FromChicken McNuggets <chicken@mcnuggets.com>
Date2012-08-23 13:27 +0100
Message-ID<k157iq$vet$1@speranza.aioe.org>
In reply to#24703
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 :).

[toc] | [prev] | [next] | [standalone]


#24750

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-08-23 11:13 -0400
Message-ID<503648B2.5000200@verizon.net>
In reply to#24747
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;
}

[toc] | [prev] | [next] | [standalone]


#24754

From"Heinrich Wolf" <invalid@invalid.invalid>
Date2012-08-23 18:18 +0200
Message-ID<k15l4r$bl3$1@news.m-online.net>
In reply to#24750
"James Kuyper" <jameskuyper@verizon.net> schrieb im Newsbeitrag 
news:503648B2.5000200@verizon.net...
...
>> 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 

[toc] | [prev] | [next] | [standalone]


#24756

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-08-23 12:40 -0400
Message-ID<50365CE4.3040302@verizon.net>
In reply to#24754
On 08/23/2012 12:18 PM, Heinrich Wolf wrote:
> 
> "James Kuyper" <jameskuyper@verizon.net> schrieb im Newsbeitrag 
> news:503648B2.5000200@verizon.net...
> ...
>>> 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.

[toc] | [prev] | [next] | [standalone]


#24755

FromAnand Hariharan <mailto.anand.hariharan@gmail.com>
Date2012-08-23 09:29 -0700
Message-ID<4d0f1992-3060-4116-a374-eed0bca6832a@a14g2000yqc.googlegroups.com>
In reply to#24750
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’

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.c


csiph-web