Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #41349 > unrolled thread
| Started by | Robbie Brown <dac@nomail.invalid> |
|---|---|
| First post | 2014-03-04 20:18 +0000 |
| Last post | 2014-03-05 11:44 +0000 |
| Articles | 20 on this page of 24 — 5 participants |
Back to article view | Back to comp.lang.c
complex declarations Robbie Brown <dac@nomail.invalid> - 2014-03-04 20:18 +0000
Re: complex declarations James Kuyper <jameskuyper@verizon.net> - 2014-03-04 15:49 -0500
Re: complex declarations James Kuyper <jameskuyper@verizon.net> - 2014-03-04 16:06 -0500
Re: complex declarations Robbie Brown <dac@nomail.invalid> - 2014-03-05 12:18 +0000
Re: complex declarations "BartC" <bc@freeuk.com> - 2014-03-05 12:56 +0000
Re: complex declarations James Kuyper <jameskuyper@verizon.net> - 2014-03-05 08:24 -0500
Re: complex declarations "BartC" <bc@freeuk.com> - 2014-03-05 16:26 +0000
Re: complex declarations James Kuyper <jameskuyper@verizon.net> - 2014-03-05 08:13 -0500
Re: complex declarations Robbie Brown <dac@nomail.invalid> - 2014-03-05 13:32 +0000
Re: complex declarations Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-05 14:32 +0000
Re: complex declarations Robbie Brown <dac@nomail.invalid> - 2014-03-04 21:42 +0000
Re: complex declarations Keith Thompson <kst-u@mib.org> - 2014-03-04 14:04 -0800
Re: complex declarations Robbie Brown <dac@nomail.invalid> - 2014-03-05 09:22 +0000
Re: complex declarations James Kuyper <jameskuyper@verizon.net> - 2014-03-05 07:29 -0500
Re: complex declarations Keith Thompson <kst-u@mib.org> - 2014-03-05 08:38 -0800
Re: complex declarations James Kuyper <jameskuyper@verizon.net> - 2014-03-04 17:05 -0500
Re: complex declarations Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-04 21:15 +0000
Re: complex declarations "BartC" <bc@freeuk.com> - 2014-03-04 21:38 +0000
Re: complex declarations Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-04 23:27 +0000
Re: complex declarations Robbie Brown <dac@nomail.invalid> - 2014-03-04 21:59 +0000
Re: complex declarations James Kuyper <jameskuyper@verizon.net> - 2014-03-04 17:12 -0500
Re: complex declarations Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-05 00:28 +0000
Re: complex declarations Robbie Brown <dac@nomail.invalid> - 2014-03-05 09:10 +0000
Re: complex declarations Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-03-05 11:44 +0000
Page 1 of 2 [1] 2 Next page →
| From | Robbie Brown <dac@nomail.invalid> |
|---|---|
| Date | 2014-03-04 20:18 +0000 |
| Subject | complex declarations |
| Message-ID | <lf5cdv$dll$1@dont-email.me> |
I have the following code
/* declare signal as function (int, pointer to function (int) returning
void) returning pointer to function (int) returning void */
void (*signal(int, void (*)(int)) ) (int);
/* simplify things a bit using a typedef */
typedef void (*fptr)(int);
int main(void){
/* declare and define function that takes int and returns void */
void foobar(int x){
printf("%s%d\n", "x in foobar is ", x);
}
/* define signal using the typedef, compiles */
fptr signal(int x, fptr y){
return NULL;
}
/* What I'd like to do now is to replace the fptr typedef with the
pre typedef type if that makes sense.
Why? because it helps my understanding */
/* Here I can say, void y(), void (y)(), void (*y)(), void y(int),
void(y)(int) void (*y)(int) for the second arg and they all
compile */
fptr signal2(int x, void (*y)(int) ){
NULL;
}
/* finally I want to do something like
return a pointer to a function taking int and returning void
but I just can't figure out how to do it. I've tried
void (*)(int), void (int), (void (*) (int)) etc etc without
success */
/* can't get this to compile in any way */
//void (*x) (int) signal3(int x, void (*y)(int) ){
// return NULL;
//}
}
How do I code signal3 to completely get rid of my dependence on the
typedef. Once again, the only reason I want to do this is because I can
(hopefully)
Thanks
--
Rob - not floundering, fishing
[toc] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-03-04 15:49 -0500 |
| Message-ID | <53163C3C.8060203@verizon.net> |
| In reply to | #41349 |
On 03/04/2014 03:18 PM, Robbie Brown wrote:
> I have the following code
>
> /* declare signal as function (int, pointer to function (int) returning
> void) returning pointer to function (int) returning void */
>
> void (*signal(int, void (*)(int)) ) (int);
>
> /* simplify things a bit using a typedef */
> typedef void (*fptr)(int);
>
> int main(void){
This location is inside the block associated with main.
> /* declare and define function that takes int and returns void */
> void foobar(int x){
> printf("%s%d\n", "x in foobar is ", x);
> }
C function definitions can only occur at file scope (6.9p1). You can
declare a function at block scope (6.8p2), but you can't define it
there. Because you can't define it with block scope, I also personally
feel it's a bad idea to declare it at file scope - but that's just a
personal preference, not a C rule.
If you got this code to compile (except for the part you're asking
about), then you're taking advantage of a non-conforming extension to C
which allows block scope definitions of functions. If making use of that
extension is important to you, then you should post your questions to a
forum specializing in the particular compiler that supports that
extension. If it supports that extension, it may support others, and
advice that you get from this newsgroup might be useless for that compiler.
> /* define signal using the typedef, compiles */
> fptr signal(int x, fptr y){
> return NULL;
> }
>
> /* What I'd like to do now is to replace the fptr typedef with the
> pre typedef type if that makes sense.
> Why? because it helps my understanding */
>
> /* Here I can say, void y(), void (y)(), void (*y)(), void y(int),
> void(y)(int) void (*y)(int) for the second arg and they all
> compile */
>
> fptr signal2(int x, void (*y)(int) ){
> NULL;
> }
>
> /* finally I want to do something like
> return a pointer to a function taking int and returning void
> but I just can't figure out how to do it. I've tried
> void (*)(int), void (int), (void (*) (int)) etc etc without
> success */
>
> /* can't get this to compile in any way */
> //void (*x) (int) signal3(int x, void (*y)(int) ){
That's because you start out declaring an identifier named x to be a
pointer to a function taking an argument of type int. Then you try to
follow that up with the declaration of signal3. You can declare the name
of a function and the names of it's arguments, but you can't declare a
name for the value returned by that function. What you want to do is to
declare signal3 as returning an UNNAMED pointer to a function taking one
argument of type int.
> // return NULL;
> //}
>
> }
>
>
> How do I code signal3 to completely get rid of my dependence on the
> typedef. Once again, the only reason I want to do this is because I can
> (hopefully)
How do you make the pointer returned by signal3 unnamed? You have to use
a type name, which syntactically looks just like the declaration of an
identifier of a function or an object, except that it omits the identifier.
void (*)(int) signal3(int x, void(*y)(int))
Type names are also used in casts and sizeof() expressions. In C99,
they're also used in compound literals. In C2011, they're also used in
_Generic() associations, _Alignof() expressions, _Atomic() type
specifiers, and _Alignas() specifiers.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-03-04 16:06 -0500 |
| Message-ID | <5316406C.9050905@verizon.net> |
| In reply to | #41352 |
On 03/04/2014 03:49 PM, James Kuyper wrote: ,,, > C function definitions can only occur at file scope (6.9p1). You can > declare a function at block scope (6.8p2), but you can't define it > there. Because you can't define it with block scope, I also personally > feel it's a bad idea to declare it at file scope - but that's just a "file" should have been "block" in that last sentence. That error almost exactly reverses my intended meaning. ... > Type names are also used in casts and sizeof() expressions. In C99, > they're also used in compound literals. In C2011, they're also used in > _Generic() associations, _Alignof() expressions, _Atomic() type > specifiers, and _Alignas() specifiers. I should also mention that function declarations are allowed to use type names for the parameters; you're only required to name the parameters in the function definition itself. This is not stated directly by the use of the phrase "type name", but only implicitly by the fact that 6.7.6p1 does not require a parameter-declaration to contain a declarator, it can use an abstract-declarator instead. That freedom is retracted for function definitions (6.9.1p5).
[toc] | [prev] | [next] | [standalone]
| From | Robbie Brown <dac@nomail.invalid> |
|---|---|
| Date | 2014-03-05 12:18 +0000 |
| Message-ID | <lf74lv$s1q$1@dont-email.me> |
| In reply to | #41353 |
On 04/03/14 21:06, James Kuyper wrote: > On 03/04/2014 03:49 PM, James Kuyper wrote: > ,,, >> C function definitions can only occur at file scope (6.9p1). You can >> declare a function at block scope (6.8p2), but you can't define it >> there. Because you can't define it with block scope, I also personally >> feel it's a bad idea to declare it at file scope - but that's just a > > "file" should have been "block" in that last sentence. That error almost > exactly reverses my intended meaning. OK, I suppose I'm pushing my luck here but I'm not entirely sure what you are saying so here goes If I have a 'program' foo.c that (tries to) comply with some seemingly nebulous set of rules that are apparently defined in the latest spec I can find 'for free' (n1256.pdf) then I can't have nested functions for one thing. So, where exactly should I define my functions? If I have an 'all in one file program' then I don't need function prototypes and I declare and define all my sub-functions, that is functions that are not main() at the top of the file, once, and use them in main(). I'd call this 'file scope'. I can also declare prototypes at the top of the file and define the functions after the end of main() although why I'd want to do this I have no idea. Also 'file scope' I can also declare prototypes at the head of main or in an include file and define them somewhere else. What scope is this? It's obviously more flexible to have a func.h and func.c dedicated 'function container' as it allows easy reuse. There are other questions, like, where's the sanity of declaring a prototype in block scope when you can't define it in same (this seems particularly bizarre) I'm trying to come up with a sane 'standard approach' to partitioning my code. I don't expect an answer as I'm not even sure of the question but it's good to get it off my chest :-) -- Rob - not floundering, fishing ======================================================== For every SCoP we generate the polyhedral representation and transform it back to gimple. ======================================================== Seems perfectly reasonable to me.
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2014-03-05 12:56 +0000 |
| Message-ID | <X9FRu.230858$IS.94538@fx01.am4> |
| In reply to | #41374 |
"Robbie Brown" <dac@nomail.invalid> wrote in message news:lf74lv$s1q$1@dont-email.me... > On 04/03/14 21:06, James Kuyper wrote: >> On 03/04/2014 03:49 PM, James Kuyper wrote: >> ,,, >>> C function definitions can only occur at file scope (6.9p1). You can >>> declare a function at block scope (6.8p2), but you can't define it >>> there. Because you can't define it with block scope, I also personally >>> feel it's a bad idea to declare it at file scope - but that's just a >> >> "file" should have been "block" in that last sentence. That error almost >> exactly reverses my intended meaning. > > OK, I suppose I'm pushing my luck here but I'm not entirely sure what you > are saying so here goes > > If I have a 'program' foo.c that (tries to) comply with some seemingly > nebulous set of rules that are apparently defined in the latest spec I can > find 'for free' (n1256.pdf) then I can't have nested functions for one > thing. So, where exactly should I define my functions? You define one after the other in the file. But not one inside the other. > If I have an 'all in one file program' then I don't need function > prototypes and I declare and define all my sub-functions, that is > functions that are not main() at the top of the file, once, and use them > in main(). I'd call this 'file scope'. Without prototypes, you need to define functions in a certain order such that a function is always defined before it is called. But that's not always possible. > I can also declare prototypes at the top of the file and define the > functions after the end of main() although why I'd want to do this I have > no idea. Also 'file scope' Because you (and people maintaining your code who are not familiar with the call-tree) then have total freedom in editing the code, moving blocks around, chopping things up, pasting from elsewhere, etc. Otherwise you have to spend some effort in making sure that all functions are in a particular order. But, if any of your functions are exported to another module, then you will need to produce prototypes for that module anyway. (Actually all C functions are exported unless you declare them with 'static'. You can also call them from elsewhere without a prototype; that's how C used to work. These days prototypes for exported/imported functions are a good idea.) > I can also declare prototypes at the head of main or in an include file > and define them somewhere else. What scope is this? It's obviously more > flexible to have a func.h and func.c dedicated 'function container' as it > allows easy reuse. > > There are other questions, like, where's the sanity of declaring a > prototype in block scope when you can't define it in same (this seems > particularly bizarre) That can work for an 'extern' function defined in another module and declared for use here. It would be unusual though to want to restrict its visibility to just that function (or even that block). > I'm trying to come up with a sane 'standard approach' to partitioning my > code. I don't expect an answer as I'm not even sure of the question but > it's good to get it off my chest :-) This is C. There isn't a standard approach. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-03-05 08:24 -0500 |
| Message-ID | <lf78hn$nat$1@dont-email.me> |
| In reply to | #41376 |
On 03/05/2014 07:56 AM, BartC wrote: > "Robbie Brown" <dac@nomail.invalid> wrote in message > news:lf74lv$s1q$1@dont-email.me... ... > But, if any of your functions are exported to another module, then you will > need to produce prototypes for that module anyway. (Actually all C functions > are exported unless you declare them with 'static'. You can also call them > from elsewhere without a prototype; that's how C used to work. These days > prototypes for exported/imported functions are a good idea.) Note to Robbie: Bartc is primarily interested in designing his own language, and uses the term "export" to describe a feature of that language. This term has no well-defined meaning in C. C functions have external linkage unless declared 'static', in which case they have internal linkage. However, they cannot be called from another translation unit without a declaration in scope in that translation unit. The declaration should be a prototype, but that's not required by the language. In C90, if a previously undeclared identifier was used as if it were a function, a declaration was implicitly created for that identifier as the name of a function returning an int and taking a fixed but unspecified number of arguments of unspecified types. This was found to be a very error-prone feature - it was removed in C99. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2014-03-05 16:26 +0000 |
| Message-ID | <0gIRu.3381$0X5.30@fx31.am4> |
| In reply to | #41378 |
"James Kuyper" <jameskuyper@verizon.net> wrote in message news:lf78hn$nat$1@dont-email.me... > On 03/05/2014 07:56 AM, BartC wrote: >> "Robbie Brown" <dac@nomail.invalid> wrote in message >> news:lf74lv$s1q$1@dont-email.me... > ... >> But, if any of your functions are exported to another module, then you >> will >> need to produce prototypes for that module anyway. (Actually all C >> functions >> are exported unless you declare them with 'static'. You can also call >> them >> from elsewhere without a prototype; that's how C used to work. These days >> prototypes for exported/imported functions are a good idea.) > > Note to Robbie: Bartc is primarily interested in designing his own > language, (Not quite true, I've been trying to avoid doing so. However....) > and uses the term "export" to describe a feature of that > language. This term has no well-defined meaning in C. C functions have > external linkage unless declared 'static', in which case they have > internal linkage. If you define a function F in translation unit A, to be called from translation unit B, would anyone really be completely flummoxed if I described F as being exported from A, and imported by B? And I tend to declare such a function F (even when writing C), with a 'global' prefix (an empty macro) in A, and with an 'extern' prefix in B. Proper C of course prefers to use no prefix when declaring F when it is defined in A, and no prefix either when declaring it in B, just to make it perfectly clear what is what! With un-exported local functions needing a 'static' prefix, obviously. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-03-05 08:13 -0500 |
| Message-ID | <lf77ub$iu8$1@dont-email.me> |
| In reply to | #41374 |
On 03/05/2014 07:18 AM, Robbie Brown wrote:
> On 04/03/14 21:06, James Kuyper wrote:
>> On 03/04/2014 03:49 PM, James Kuyper wrote:
>> ,,,
>>> C function definitions can only occur at file scope (6.9p1). You can
>>> declare a function at block scope (6.8p2), but you can't define it
>>> there. Because you can't define it with block scope, I also personally
>>> feel it's a bad idea to declare it at file scope - but that's just a
>>
>> "file" should have been "block" in that last sentence. That error almost
>> exactly reverses my intended meaning.
>
> OK, I suppose I'm pushing my luck here but I'm not entirely sure what
> you are saying so here goes
>
> If I have a 'program' foo.c that (tries to) comply with some seemingly
> nebulous set of rules that are apparently defined in the latest spec I
> can find 'for free' (n1256.pdf) then I can't have nested functions for
> one thing. So, where exactly should I define my functions?
At file scope, in as many or as few different files as you like.
> If I have an 'all in one file program' then I don't need function
> prototypes and I declare and define all my sub-functions, that is
> functions that are not main() at the top of the file, once, and use them
> in main(). I'd call this 'file scope'.
>
> I can also declare prototypes at the top of the file and define the
> functions after the end of main() although why I'd want to do this I
> have no idea. Also 'file scope'
Some people (not including myself) prefer that approach because they
consider it more logical.
> I can also declare prototypes at the head of main or in an include file
> and define them somewhere else. What scope is this?
That depends upon what you mean by "head of main", and where you
#include the header file:
bar.h:
#ifndef H_BAR
#define H_BAR
int bar(int);
#endif
foo.h:
#ifndef H_FOO
#define H_FOO
void foo();
#endif
main.c:
// Is this what you mean by "head of main"?
// create a file scope declaration for bar():
#include "bar.h"
int file_scope_declaration(double);
int main()
{
// Or is this what you mean by "head of main"?
// NB: I do NOT recommend block scope function declarations
double block_scope_declaration(int);
// Create block scope declaration for foo()
#include "foo.h"
// Do NOT do this with any standard header - the behavior is
// undefined (7.1.2p4).
foo();
return bar(file_scope_declaration(block_scope_declaration(0));
}
> There are other questions, like, where's the sanity of declaring a
> prototype in block scope when you can't define it in same (this seems
> particularly bizarre)
While I agree with you about that, those who disagree with us say that
by doing so, they're limiting the scope of the prototype, reducing the
danger of naming conflicts.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Robbie Brown <dac@nomail.invalid> |
|---|---|
| Date | 2014-03-05 13:32 +0000 |
| Message-ID | <lf790u$r13$1@dont-email.me> |
| In reply to | #41377 |
On 05/03/14 13:13, James Kuyper wrote:
> On 03/05/2014 07:18 AM, Robbie Brown wrote:
>> On 04/03/14 21:06, James Kuyper wrote:
>>> On 03/04/2014 03:49 PM, James Kuyper wrote:
>>> ,,,
>>>> C function definitions can only occur at file scope (6.9p1). You can
>>>> declare a function at block scope (6.8p2), but you can't define it
>>>> there. Because you can't define it with block scope, I also personally
>>>> feel it's a bad idea to declare it at file scope - but that's just a
>>>
>>> "file" should have been "block" in that last sentence. That error almost
>>> exactly reverses my intended meaning.
>>
>> OK, I suppose I'm pushing my luck here but I'm not entirely sure what
>> you are saying so here goes
<snip>
> That depends upon what you mean by "head of main", and where you
> #include the header file:
>
> bar.h:
> #ifndef H_BAR
> #define H_BAR
> int bar(int);
> #endif
>
> foo.h:
> #ifndef H_FOO
> #define H_FOO
> void foo();
> #endif
>
> main.c:
> // Is this what you mean by "head of main"?
Yes, my fault for not being clear.
I think I've probably got this now, interesting point about defining
functions after main(). I can see some sense in that now.
> // create a file scope declaration for bar():
> #include "bar.h"
> int file_scope_declaration(double);
>
> int main()
> {
> // Or is this what you mean by "head of main"?
> // NB: I do NOT recommend block scope function declarations
> double block_scope_declaration(int);
> // Create block scope declaration for foo()
> #include "foo.h"
> // Do NOT do this with any standard header - the behavior is
> // undefined (7.1.2p4).
Yea, I'd probably run screaming into the night if I came across this.
Never even considered it.
--
Rob - not floundering, fishing
========================================================
For every SCoP we generate the polyhedral representation
and transform it back to gimple.
========================================================
Seems perfectly reasonable to me.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2014-03-05 14:32 +0000 |
| Message-ID | <0.6152c1dc32819d503544.20140305143203GMT.87y50o90nw.fsf@bsb.me.uk> |
| In reply to | #41374 |
Robbie Brown <dac@nomail.invalid> writes: <snip> > There are other questions, like, where's the sanity of declaring a > prototype in block scope when you can't define it in same (this seems > particularly bizarre) Yes, but it's easy to support and it would seem strange to outlaw it for no good reason. The prohibition on *defining* function inside others is due to the fact that it might impose extra costs on the implementation. I say "might" because I think gcc has found a way to avoid the cost except when it must be paid, but in the early days of C I suspect the cost was seen as being inevitable. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Robbie Brown <dac@nomail.invalid> |
|---|---|
| Date | 2014-03-04 21:42 +0000 |
| Message-ID | <lf5hca$oqi$1@dont-email.me> |
| In reply to | #41352 |
On 04/03/14 20:49, James Kuyper wrote:
> On 03/04/2014 03:18 PM, Robbie Brown wrote:
>> I have the following code
<snip>
> C function definitions can only occur at file scope (6.9p1). You can
> declare a function at block scope (6.8p2), but you can't define it
> there. Because you can't define it with block scope, I also personally
> feel it's a bad idea to declare it at file scope - but that's just a
> personal preference, not a C rule.
>
> If you got this code to compile (except for the part you're asking
> about), then you're taking advantage of a non-conforming extension to C
> which allows block scope definitions of functions.
I used gcc -std=c99 complexdecl.c and you are right. Apparently the
ability to define a function within a function (nesting of functions) is
a gcc extension, sheesh, you really gotta be on the ball with this stuff
haven't you?
<snip>
> That's because you start out declaring an identifier named x to be a
> pointer to a function taking an argument of type int. Then you try to
> follow that up with the declaration of signal3. You can declare the name
> of a function and the names of it's arguments, but you can't declare a
> name for the value returned by that function. What you want to do is to
> declare signal3 as returning an UNNAMED pointer to a function taking one
> argument of type int.
<snip>
>> How do I code signal3 to completely get rid of my dependence on the
>> typedef. Once again, the only reason I want to do this is because I can
>> (hopefully)
>
> How do you make the pointer returned by signal3 unnamed? You have to use
> a type name, which syntactically looks just like the declaration of an
> identifier of a function or an object, except that it omits the identifier.
>
> void (*)(int) signal3(int x, void(*y)(int))
That was one of the first things I tried and for some reason that
(obviously) escapes me it doesn't compile.
So, I simplified the code, now I have (with emacs line no's)
3. void (*signal(int, void (*)(int)) ) (int);
4.
5. void (*) (int) sig(int x, void (*y)(int) ){
6. return NULL;
7. }
8.
9. int main(void){
10.
11. }
I used gcc -std=c99 complexdecl.c
Compilation failed with
complexdecl.c:5:8: error: expected identifier or ‘(’ before ‘)’ token
5:8 is just after the leftmost ) in the definition.
Just for a laugh I tried with sig nested inside main and still failure.
I have also tried -std=gnu99 as I noticed that that can do some weird
stuff.
Like I say, one of the first things I tried was
void (*) (int) sig(int x, void (*y)(int) ) and I was surprised
that it didn't compile.
Obviously I'm missing something here but I don't really know what to try
next. Any ideas much appreciated.
Thanks
--
Rob - not floundering, fishing
========================================================
For every SCoP we generate the polyhedral representation
and transform it back to gimple.
========================================================
Seems perfectly reasonable to me.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2014-03-04 14:04 -0800 |
| Message-ID | <lnob1lwrgy.fsf@nuthaus.mib.org> |
| In reply to | #41356 |
Robbie Brown <dac@nomail.invalid> writes:
> On 04/03/14 20:49, James Kuyper wrote:
>> On 03/04/2014 03:18 PM, Robbie Brown wrote:
>>> I have the following code
>
> <snip>
>
>> C function definitions can only occur at file scope (6.9p1). You can
>> declare a function at block scope (6.8p2), but you can't define it
>> there. Because you can't define it with block scope, I also personally
>> feel it's a bad idea to declare it at file scope - but that's just a
>> personal preference, not a C rule.
>>
>> If you got this code to compile (except for the part you're asking
>> about), then you're taking advantage of a non-conforming extension to C
>> which allows block scope definitions of functions.
>
> I used gcc -std=c99 complexdecl.c and you are right. Apparently the
> ability to define a function within a function (nesting of functions) is
> a gcc extension, sheesh, you really gotta be on the ball with this stuff
> haven't you?
Use "gcc -std=c99 -pedantic" to make it warn about violations of the C99
standard. gcc is not a conforming C compiler without the "-pedantic"
option. Use "-pedantic-warnings" to turn those warnings into fatal
errors.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <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"
[toc] | [prev] | [next] | [standalone]
| From | Robbie Brown <dac@nomail.invalid> |
|---|---|
| Date | 2014-03-05 09:22 +0000 |
| Message-ID | <lf6qd4$m55$1@dont-email.me> |
| In reply to | #41358 |
On 04/03/14 22:04, Keith Thompson wrote: > Robbie Brown <dac@nomail.invalid> writes: >> On 04/03/14 20:49, James Kuyper wrote: >>> On 03/04/2014 03:18 PM, Robbie Brown wrote: >>>> I have the following code <snip> > Use "gcc -std=c99 -pedantic" to make it warn about violations of the C99 > standard. gcc is not a conforming C compiler without the "-pedantic" > option. Use "-pedantic-warnings" to turn those warnings into fatal > errors. OK, well my gcc doesn't support -pedantic-warnings. However -pedantic warns and still produces an executable -pedantic-errors produces an error message and does not produce an executable, so I guess it's the same difference. It's a bit of a minefield though isn't it? Now I know there's no such thing but Does the 'average C developer' actually need to know all this all the time or do people often/sometimes 'specialize' in a particular compiler implementation along with it's extensions? Thanks for the reply -- Rob - not floundering, fishing ======================================================== For every SCoP we generate the polyhedral representation and transform it back to gimple. ======================================================== Seems perfectly reasonable to me.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-03-05 07:29 -0500 |
| Message-ID | <lf75b0$au$1@dont-email.me> |
| In reply to | #41371 |
On 03/05/2014 04:22 AM, Robbie Brown wrote: > On 04/03/14 22:04, Keith Thompson wrote: >> Robbie Brown <dac@nomail.invalid> writes: >>> On 04/03/14 20:49, James Kuyper wrote: >>>> On 03/04/2014 03:18 PM, Robbie Brown wrote: >>>>> I have the following code > > <snip> > >> Use "gcc -std=c99 -pedantic" to make it warn about violations of the C99 >> standard. gcc is not a conforming C compiler without the "-pedantic" >> option. Use "-pedantic-warnings" to turn those warnings into fatal >> errors. > > OK, well my gcc doesn't support -pedantic-warnings. I'm pretty sure that was a typo for -pedantic-errors > However > > -pedantic warns and still produces an executable > -pedantic-errors produces an error message and does not produce an > executable, so I guess it's the same difference. I don't usually bother with -pedantic-errors, but there is a real benefit to using it: if there is no executable, you can't be tempted to try executing it. > It's a bit of a minefield though isn't it? > > Now I know there's no such thing but > Does the 'average C developer' actually need to know all this all the > time or do people often/sometimes 'specialize' in a particular compiler > implementation along with it's extensions? Most people specialize in some way - my personal choice was to specialize in writing to the C standard, avoiding compiler-specific extensions, but that's mainly because my company's client has imposed a strong portability requirements on our code. You should be able to compile and successfully execute our code on any system with sufficient memory and disk space that supports POSIX (1003.1, IIRC) and C95. you might have to make minor modifications to the make file, but you shouldn't have to do anything to the source code to make it work. I avoid even depending upon POSIX unless necessary. Some of my code relies on POSIX's guarantee that CHAR_BIT == 8; but most of it would continue to work properly even if that weren't true. People writing code that has weaker portability requirements can and usually do justify learning more about the quirks of a particular compiler than I ever have. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2014-03-05 08:38 -0800 |
| Message-ID | <lnk3c8wqfz.fsf@nuthaus.mib.org> |
| In reply to | #41375 |
James Kuyper <jameskuyper@verizon.net> writes:
> On 03/05/2014 04:22 AM, Robbie Brown wrote:
>> On 04/03/14 22:04, Keith Thompson wrote:
[...]
>>> Use "gcc -std=c99 -pedantic" to make it warn about violations of the C99
>>> standard. gcc is not a conforming C compiler without the "-pedantic"
>>> option. Use "-pedantic-warnings" to turn those warnings into fatal
>>> errors.
>>
>> OK, well my gcc doesn't support -pedantic-warnings.
>
> I'm pretty sure that was a typo for -pedantic-errors
Yes.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <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"
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2014-03-04 17:05 -0500 |
| Message-ID | <53164E3B.3090800@verizon.net> |
| In reply to | #41356 |
On 03/04/2014 04:42 PM, Robbie Brown wrote: > On 04/03/14 20:49, James Kuyper wrote: >> On 03/04/2014 03:18 PM, Robbie Brown wrote: >>> I have the following code > > <snip> > >> C function definitions can only occur at file scope (6.9p1). You can >> declare a function at block scope (6.8p2), but you can't define it >> there. Because you can't define it with block scope, I also personally >> feel it's a bad idea to declare it at file scope - but that's just a >> personal preference, not a C rule. >> >> If you got this code to compile (except for the part you're asking >> about), then you're taking advantage of a non-conforming extension to C >> which allows block scope definitions of functions. > > I used gcc -std=c99 complexdecl.c and you are right. Apparently the > ability to define a function within a function (nesting of functions) is > a gcc extension, sheesh, you really gotta be on the ball with this stuff > haven't you? If you add "-pedantic" to "-std=c99", you will have eliminated most of your dependence on gcc extensions, though I personally would recommend adding "-Wall -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wmissing-prototypes" as well. Other people like to turn on several additional warnings, particularly -Wextra, but I find a lot of those warnings to be spurious. > <snip> > >> That's because you start out declaring an identifier named x to be a >> pointer to a function taking an argument of type int. Then you try to >> follow that up with the declaration of signal3. You can declare the name >> of a function and the names of it's arguments, but you can't declare a >> name for the value returned by that function. <snip incorrect advice from my previous message, except for final recommendation:> ... >> void (*)(int) signal3(int x, void(*y)(int)) > > That was one of the first things I tried and for some reason that > (obviously) escapes me it doesn't compile. That's because I managed to get confused during the process of responding to you. I put a lot of effort into making that message complete; I should have put a bit more effort into making it correct. A simple test compile would have reminded me of my error, and I would have known how to correct it, but I didn't do such a test. Ben's answer is the correct one, and it renders irrelevant everything I said about type names. It was all correct (I think), except for the part about a type name being the answer to your problem. :-(
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2014-03-04 21:15 +0000 |
| Message-ID | <0.6deb784efb3a9c1024d1.20140304211557GMT.87txbdbr76.fsf@bsb.me.uk> |
| In reply to | #41349 |
Robbie Brown <dac@nomail.invalid> writes:
> I have the following code
>
> /* declare signal as function (int, pointer to function (int)
> returning void) returning pointer to function (int) returning void */
>
> void (*signal(int, void (*)(int)) ) (int);
>
> /* simplify things a bit using a typedef */
> typedef void (*fptr)(int);
>
> int main(void){
>
> /* declare and define function that takes int and returns void */
> void foobar(int x){
> printf("%s%d\n", "x in foobar is ", x);
> }
Nested functions are an extension. The fact that your code compiles
means you are not using the compiler in its strictest mode. When you
are trying to understand things, it helps to get the compiler to tell
you as much a possible and using this extension prevents you from doing
that.
> /* define signal using the typedef, compiles */
> fptr signal(int x, fptr y){
> return NULL;
> }
>
> /* What I'd like to do now is to replace the fptr typedef with the
> pre typedef type if that makes sense.
> Why? because it helps my understanding */
>
> /* Here I can say, void y(), void (y)(), void (*y)(), void y(int),
> void(y)(int) void (*y)(int) for the second arg and they all
> compile */
>
> fptr signal2(int x, void (*y)(int) ){
> NULL;
> }
>
> /* finally I want to do something like
> return a pointer to a function taking int and returning void
> but I just can't figure out how to do it. I've tried
> void (*)(int), void (int), (void (*) (int)) etc etc without
> success */
>
> /* can't get this to compile in any way */
> //void (*x) (int) signal3(int x, void (*y)(int) ){
> // return NULL;
> //}
>
> }
>
> How do I code signal3 to completely get rid of my dependence on the
> typedef. Once again, the only reason I want to do this is because I
> can (hopefully)
You gave the declaration of such a function right at the top of the post:
void (*signal(int, void (*)(int)) ) (int);
To convert the declaration to a definition, give the parameters names
and replace the ';' with the function body.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2014-03-04 21:38 +0000 |
| Message-ID | <cKrRu.1365$k11.765@fx14.am4> |
| In reply to | #41354 |
"Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message news:0.6deb784efb3a9c1024d1.20140304211557GMT.87txbdbr76.fsf@bsb.me.uk... > Robbie Brown <dac@nomail.invalid> writes: >> void (*signal(int, void (*)(int)) ) (int); >> How do I code signal3 to completely get rid of my dependence on the >> typedef. Once again, the only reason I want to do this is because I >> can (hopefully) > > You gave the declaration of such a function right at the top of the post: > > void (*signal(int, void (*)(int)) ) (int); > > To convert the declaration to a definition, give the parameters names > and replace the ';' with the function body. Which ones are the parameters?! (I ran this with CDECL (http://www.lemoda.net/c/cdecl/index.cgi) which was only mildly helpful, even after I varied the ints a bit so I could see which was which. I /think/ the first parameter name goes after the first int, and the second one after the * in (*).) -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2014-03-04 23:27 +0000 |
| Message-ID | <0.24a2a8577ef8e1bf655b.20140304232706GMT.87ob1lbl4l.fsf@bsb.me.uk> |
| In reply to | #41355 |
"BartC" <bc@freeuk.com> writes: > "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message > news:0.6deb784efb3a9c1024d1.20140304211557GMT.87txbdbr76.fsf@bsb.me.uk... >> Robbie Brown <dac@nomail.invalid> writes: > >>> void (*signal(int, void (*)(int)) ) (int); > >>> How do I code signal3 to completely get rid of my dependence on the >>> typedef. Once again, the only reason I want to do this is because I >>> can (hopefully) >> >> You gave the declaration of such a function right at the top of the post: >> >> void (*signal(int, void (*)(int)) ) (int); >> >> To convert the declaration to a definition, give the parameters names >> and replace the ';' with the function body. > > Which ones are the parameters?! void (*signal(int signum, void (*newaction)(int)) ) (int); > (I ran this with CDECL (http://www.lemoda.net/c/cdecl/index.cgi) which was > only mildly helpful, even after I varied the ints a bit so I could see which > was which. > > I /think/ the first parameter name goes after the first int, and the second > one after the * in (*).) Yes. How can one tell? Well, signal is a function because its name is followed by an (. That ( starts the comma separated list of parameters that ends with the matching ). I.e. this is the parameter list: int, void (*)(int) It's clear where the first name goes. The second is a little harder but we know it's a pointer parameter and pointer types always have a * to the immediate left of the name. There's only one place to put a name so that it has a * immediately on to the left. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Robbie Brown <dac@nomail.invalid> |
|---|---|
| Date | 2014-03-04 21:59 +0000 |
| Message-ID | <lf5ic0$9q$1@dont-email.me> |
| In reply to | #41354 |
On 04/03/14 21:15, Ben Bacarisse wrote:
> Robbie Brown <dac@nomail.invalid> writes:
>
>> I have the following code
>>
>> /* declare signal as function (int, pointer to function (int)
>> returning void) returning pointer to function (int) returning void */
>>
>> void (*signal(int, void (*)(int)) ) (int);
>>
>> /* simplify things a bit using a typedef */
>> typedef void (*fptr)(int);
>>
>> int main(void){
>>
>> /* declare and define function that takes int and returns void */
>> void foobar(int x){
>> printf("%s%d\n", "x in foobar is ", x);
>> }
>
> Nested functions are an extension. The fact that your code compiles
> means you are not using the compiler in its strictest mode. When you
> are trying to understand things, it helps to get the compiler to tell
> you as much a possible and using this extension prevents you from doing
> that.
>
>> /* define signal using the typedef, compiles */
>> fptr signal(int x, fptr y){
>> return NULL;
>> }
>>
>> /* What I'd like to do now is to replace the fptr typedef with the
>> pre typedef type if that makes sense.
>> Why? because it helps my understanding */
>>
>> /* Here I can say, void y(), void (y)(), void (*y)(), void y(int),
>> void(y)(int) void (*y)(int) for the second arg and they all
>> compile */
>>
>> fptr signal2(int x, void (*y)(int) ){
>> NULL;
>> }
>>
>> /* finally I want to do something like
>> return a pointer to a function taking int and returning void
>> but I just can't figure out how to do it. I've tried
>> void (*)(int), void (int), (void (*) (int)) etc etc without
>> success */
>>
>> /* can't get this to compile in any way */
>> //void (*x) (int) signal3(int x, void (*y)(int) ){
>> // return NULL;
>> //}
>>
>> }
>>
>> How do I code signal3 to completely get rid of my dependence on the
>> typedef. Once again, the only reason I want to do this is because I
>> can (hopefully)
>
> You gave the declaration of such a function right at the top of the post:
>
> void (*signal(int, void (*)(int)) ) (int);
>
> To convert the declaration to a definition, give the parameters names
> and replace the ';' with the function body.
OK, I did this and ... it compiles, now my brain hurts
void (*signal(int x, void (*i)(int y)) ) (int z){
return NULL;
}
I just can't see how the above and
typedef void (*fptr)(int);
fptr signal (int x, fptr);
which also compiles are equivalent
What a headbanger.
--
Rob - not floundering, fishing
========================================================
For every SCoP we generate the polyhedral representation
and transform it back to gimple.
========================================================
Seems perfectly reasonable to me.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web