digitalmars.D - K&R-style variadic functions
- Jacob Carlborg (15/15) Jul 16 2012 To my understanding this is legal C :
- Mehrdad (2/6) Jul 17 2012 My eyes!! They're bleeding!!
- Paulo Pinto (3/11) Jul 17 2012 I had the "pleasure" to use K&R C in my early C days, around
- Jacob Carlborg (6/7) Jul 17 2012 First I wanted to know if my interpretation is correct and then I was
- Regan Heath (47/52) Jul 17 2012 After a bit of googling and a test with my local MSVC9 I think old-style...
- Regan Heath (74/98) Jul 17 2012 Some follow up information, for interests sake.
- Jacob Carlborg (4/10) Jul 17 2012 It could just as well be no parameters.
- Regan Heath (10/18) Jul 17 2012 I believe old-style no parameter function declarations MUST have "void" ...
- Jacob Carlborg (8/14) Jul 17 2012 Take a look at this:
- Regan Heath (34/49) Jul 17 2012 Ahh, I've been looking at the ANSI C spec and assuming that is what you'...
- Jacob Carlborg (9/39) Jul 17 2012 This page says otherwise:
- Regan Heath (19/29) Jul 18 2012 The full quote:
- Regan Heath (7/7) Jul 18 2012 In any case. It think the practical solution to this problem is to assu...
- Jacob Carlborg (4/11) Jul 18 2012 Seems like this will be the solution.
- Regan Heath (13/28) Jul 17 2012 K&R C did not allow you to declare arguments at all, according to the wi...
- Paulo Pinto (9/48) Jul 17 2012 K&R was more than that.
- H. S. Teoh (21/29) Jul 17 2012 This modern C declaration:
- Matt Soucy (6/33) Jul 17 2012 Definitely - I live in a very technologically-savvy dorm in college, and...
- Paulo Pinto (12/20) Jul 17 2012 I started coding in C around 1993 with Turbo C 2.0, but was
- Regan Heath (11/30) Jul 18 2012 Clarification.
- H. S. Teoh (11/37) Jul 18 2012 [...]
- Jacob Carlborg (5/28) Jul 17 2012 Clang seems to interpret it as a variadic function. Then if that is
- Regan Heath (7/44) Jul 17 2012 All my googling for "old style" "variadic" etc returned the use of
- Jacob Carlborg (6/9) Jul 17 2012 To be accurate it's the libclang function "clang_isFunctionTypeVariadic"...
- Regan Heath (8/15) Jul 17 2012 Is Clang open source, can we see the code for that function? Perhaps it...
- Paulo Pinto (4/24) Jul 17 2012 In C++, a function with no parameters () is a synonym for (void).
- Regan Heath (7/29) Jul 18 2012 That's what I've been assuming all this time, but I wasn't sure if I was...
- Jacob Carlborg (6/11) Jul 17 2012 Sure:
- Regan Heath (9/18) Jul 18 2012 It certainly seems intentional:
- deadalnix (2/9) Jul 17 2012 It is used in testfptr.d from dmd's testsuite.
- Daniel Murphy (3/4) Jul 17 2012 No, that's a D-linkage variadic.
- Lukasz (38/38) Jul 17 2012 I was sure that if function is declared with empty () than you
- Walter Bright (16/20) Jul 18 2012 Variadic functions, in order to work in C, need at least one parameter s...
- Jacob Carlborg (22/37) Jul 18 2012 Sounds reasonable. I will also provide a flag specifying how this should...
- Walter Bright (3/7) Jul 18 2012 That is void foo(void) in C++.
- Jacob Carlborg (4/13) Jul 18 2012 --
- Walter Bright (2/10) Jul 18 2012 How would you get the arguments inside foo?
- Jacob Carlborg (6/7) Jul 18 2012 I don't know, you're the compiler writer :) I don't know these kind of
- Paulo Pinto (3/14) Jul 19 2012 As described here,
- Regan Heath (33/48) Jul 19 2012 That /requires/ an argument in the definition (AFAIKS), e.g.
- Jacob Carlborg (13/14) Jul 19 2012 Note that it only works when compiling as C++. Perhaps it works like thi...
To my understanding this is legal C : int foo (); It's a K&R-style variadic functions, while their use is discouraged, they're still legal C. If I, in D, declare a variadic function with C linkage that doesn't take, at least, one regular parameter the compiler will complain. extern (C) int foo (...); Error: variadic functions with non-D linkage must have at least one parameter Does that mean I can't use a function like this from D? I'm trying to figure out what my tool, DStep, should do when it encounters a function like this. https://github.com/jacob-carlborg/dstep -- /Jacob Carlborg
Jul 16 2012
On Tuesday, 17 July 2012 at 06:56:17 UTC, Jacob Carlborg wrote:To my understanding this is legal C : int foo (); It's a K&R-style variadic functions, while their use is discouraged, they're still legal C.My eyes!! They're bleeding!!
Jul 17 2012
On Tuesday, 17 July 2012 at 07:06:38 UTC, Mehrdad wrote:On Tuesday, 17 July 2012 at 06:56:17 UTC, Jacob Carlborg wrote:I had the "pleasure" to use K&R C in my early C days, around 1992, yuck!To my understanding this is legal C : int foo (); It's a K&R-style variadic functions, while their use is discouraged, they're still legal C.My eyes!! They're bleeding!!
Jul 17 2012
On 2012-07-17 09:06, Mehrdad wrote:My eyes!! They're bleeding!!First I wanted to know if my interpretation is correct and then I was trying to figure out how my tool should behave if it encounters a function like this. -- /Jacob Carlborg
Jul 17 2012
On Tue, 17 Jul 2012 12:43:46 +0100, Jacob Carlborg <doob me.com> wrote:On 2012-07-17 09:06, Mehrdad wrote:After a bit of googling and a test with my local MSVC9 I think old-style variadics look like this: #include <varargs.h> #include <stdio.h> void foo(va_alist) va_dcl { va_list p; va_start(p); vprintf("%d %d %d\n", p); } void main() { foo(1, 2, 3); } (the above runs and outputs "1 2 3" on the console) The same syntax is/was supported by GNU C, see: http://ftp.gnu.org/old-gnu/Manuals/glibc-2.2.3/html_chapter/libc_34.html#SEC676 I believe, if you see an "old-style" function declaration in a header file like: int foo (); that you can't actually assume anything about it's parameters, it may have /any/ number of parameters, and may or may not be variadic. e.g. see: http://msdn.microsoft.com/en-us/library/efx873ys.aspx The "declaration" syntax shown there for a function with 2 arguments is simply: double old_style(); In short, I don't think you can produce a valid .di/d file for old-style declarations automatically, it will require a manual step where the user enters the function type-arguments. However, if you see an old-style: int foo(void); you can be sure it has 0 parameters and can happily produce: extern (C) int foo(); So, I think you should assume no old-style function declarations but have a command line option/mode which assumes all functions declarations are old-style. In this mode you would output something like.. extern (C) <return-type> <function-name>(/*TODO: add args here*/); and require the user manually find and define these. I can't think of any other way you could do it. R p.s. I found this copy of the C spec online: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf section 6.7.5.3 appears to deal with function declarations. -- Using Opera's revolutionary email client: http://www.opera.com/mail/My eyes!! They're bleeding!!First I wanted to know if my interpretation is correct and then I was trying to figure out how my tool should behave if it encounters a function like this.
Jul 17 2012
On Tue, 17 Jul 2012 13:32:08 +0100, Regan Heath <regan netmail.co.nz> wrote:On Tue, 17 Jul 2012 12:43:46 +0100, Jacob Carlborg <doob me.com> wrote:Some follow up information, for interests sake. 1. va_dcl is defined in varargs.h as.. #define va_dcl va_list va_alist; So, the old-style variable args function definiton can be written: void foo(va_alist) va_list va_alist; { ... } 2. va_start in defined in varargs.h as.. #define va_start(ap) ap = (va_list)&va_alist So, it assumes a parameter called va_alist exists, and it simply takes the address of it. A new style variadic uses a definition like this.. #define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) ) which takes the address of 'v' (which is the argument prior to the ...) then skips past it, obtaining the address of the first ... argument. So, in effect they are doing the same thing, taking the address of the first variable argument. In which case, I can only assume if we can call new-style variadics from D, we can call old-style ones as well - provided any preceding arguments to the va_alist argument are defined correctly, .e.g. given this old-style function declaration: void foo(); which actually happens to match this old-style variadic function definition: void foo(a,b,va_alist) int a; int b; va_list va_alist; { } we could produce the following: extern (C) void foo(/*TODO: add args here*/); and, once the user filled in the args extern (C) void foo(int a, int b, ...); it should be callable from D.. in fact I just did a test (albeit with a slightly different test case..) [testdll.c] #include <varargs.h> #include <stdio.h> __declspec( dllexport ) void foo(va_alist) va_list va_alist; { va_list p; va_start(p); vprintf("%d %d %d\n", p); } (compiled with MSVC to dll and lib, lib converted with coffimplib to OMF format) [test.d] extern (C) void foo(int a, ...); int main(string[] args) { foo(1, 3, 5); return 0; } compile with dmd test.d testdll.lib, run test.exe, outputs "1 3 5" :) But, this highlights one issue I was unaware of. The D extern (C) declaration needs at least 1 parameter before the ..., having just: extern (C) void foo(...); is illegal. In my specific case I could add "int a" as the first parameter, and all was well. Each case will be different, and it's conceivable there is a C old-style variadic which takes /any/ type of first parameter, which could be a problem, however the key issue is the size of the argument. If all types which could be passed are 32 bits big, then "int a" is sufficient to get it working in all cases. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/On 2012-07-17 09:06, Mehrdad wrote:After a bit of googling and a test with my local MSVC9 I think old-style variadics look like this: #include <varargs.h> #include <stdio.h> void foo(va_alist) va_dcl { va_list p; va_start(p); vprintf("%d %d %d\n", p); } void main() { foo(1, 2, 3); } (the above runs and outputs "1 2 3" on the console)My eyes!! They're bleeding!!First I wanted to know if my interpretation is correct and then I was trying to figure out how my tool should behave if it encounters a function like this.
Jul 17 2012
On 2012-07-17 15:05, Regan Heath wrote:In my specific case I could add "int a" as the first parameter, and all was well. Each case will be different, and it's conceivable there is a C old-style variadic which takes /any/ type of first parameter, which could be a problem, however the key issue is the size of the argument. If all types which could be passed are 32 bits big, then "int a" is sufficient to get it working in all cases.It could just as well be no parameters. -- /Jacob Carlborg
Jul 17 2012
On Tue, 17 Jul 2012 15:01:02 +0100, Jacob Carlborg <doob me.com> wrote:On 2012-07-17 15:05, Regan Heath wrote:I believe old-style no parameter function declarations MUST have "void" i.e. int foo(void); They cannot read: int foo(); The latter MUST have parameters, we just can't tell what they are. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/In my specific case I could add "int a" as the first parameter, and all was well. Each case will be different, and it's conceivable there is a C old-style variadic which takes /any/ type of first parameter, which could be a problem, however the key issue is the size of the argument. If all types which could be passed are 32 bits big, then "int a" is sufficient to get it working in all cases.It could just as well be no parameters.
Jul 17 2012
On 2012-07-17 16:36, Regan Heath wrote:I believe old-style no parameter function declarations MUST have "void" i.e. int foo(void);That is still the case, regardless of "style"?They cannot read: int foo(); The latter MUST have parameters, we just can't tell what they are.Take a look at this: http://en.wikipedia.org/wiki/K%26R_C#KRC In that example none of the functions have any parameters declared and are not called with any arguments. -- /Jacob Carlborg
Jul 17 2012
On Tue, 17 Jul 2012 15:46:34 +0100, Jacob Carlborg <doob me.com> wrote:On 2012-07-17 16:36, Regan Heath wrote:Ahh, I've been looking at the ANSI C spec and assuming that is what you're basing things off, K&R C was pre-ANSI C and may have different rules. I think you should probably aim to be ANSI C compliant and above, and ignore K&R. Looking at the ANSI C spec again, section 6.7.5.3, item 10 says: "The special case of an unnamed parameter of type void as the only item in the list specifies that the function has no parameters." So, "void" indicates no parameters.. Item 14 is also applicable and says: "An identifier list declares only the identifiers of the parameters of the function. An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters. The empty list in a function declarator that is not part of a definition of that function specifies that no information about the number or types of the parameters is supplied." 124) The latter part of that is applicable to declarations in header files (the former is for definitions in c files); "The empty list in a function declarator that is /not part of a definition of that function/ specifies that /no information about the number or types of the parameters is supplied/." So, a function like: int foo(); in a header "specifies that no information about the number or types of the parameters is supplied". However footnote 124) says see 6.1.6, and 6.1.6 says: 6.11.6 Function declarators The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature. So, coming full circle, it seems like I'm right after all .. I think. "void" is required to indicate no parameters and () is obsolete in ANSI C. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/I believe old-style no parameter function declarations MUST have "void" i.e. int foo(void);That is still the case, regardless of "style"?They cannot read: int foo(); The latter MUST have parameters, we just can't tell what they are.Take a look at this: http://en.wikipedia.org/wiki/K%26R_C#KRC In that example none of the functions have any parameters declared and are not called with any arguments.
Jul 17 2012
On 2012-07-17 17:11, Regan Heath wrote:Ahh, I've been looking at the ANSI C spec and assuming that is what you're basing things off, K&R C was pre-ANSI C and may have different rules. I think you should probably aim to be ANSI C compliant and above, and ignore K&R.This page says otherwise: http://en.wikipedia.org/wiki/ANSI_C#Compliance_detectability "...while an obsolescent non-prototype declaration is used otherwise. Those are still ANSI-compliant as of C99 and C90, but their use is discouraged".Looking at the ANSI C spec again, section 6.7.5.3, item 10 says: "The special case of an unnamed parameter of type void as the only item in the list specifies that the function has no parameters." So, "void" indicates no parameters.. Item 14 is also applicable and says: "An identifier list declares only the identifiers of the parameters of the function. An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters. The empty list in a function declarator that is not part of a definition of that function specifies that no information about the number or types of the parameters is supplied." 124) The latter part of that is applicable to declarations in header files (the former is for definitions in c files); "The empty list in a function declarator that is /not part of a definition of that function/ specifies that /no information about the number or types of the parameters is supplied/." So, a function like: int foo(); in a header "specifies that no information about the number or types of the parameters is supplied". However footnote 124) says see 6.1.6, and 6.1.6 says: 6.11.6 Function declarators The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature. So, coming full circle, it seems like I'm right after all .. I think. "void" is required to indicate no parameters and () is obsolete in ANSI C.It's still in the standard. -- /Jacob Carlborg
Jul 17 2012
On Tue, 17 Jul 2012 20:31:19 +0100, Jacob Carlborg <doob me.com> wrote:On 2012-07-17 17:11, Regan Heath wrote:The full quote: "In the above example, a prototype is used in a function declaration for ANSI compliant implementations, while an obsolescent non-prototype declaration is used otherwise. Those are still ANSI-compliant as of C99 and C90, but their use is discouraged." 1) "a prototype is used in a function declaration for ANSI compliant implementations" implies an ANSI compliant compiler /requires/ the full prototype. 2) "obsolescent non-prototype declaration is used otherwise" implies non-prototype forms are /obsolete/ 3) "Those are still" what is being referred to by the word "those" in that sentence, it's not immediately clear to me. It could mean the non-prototype (as you've assumed) but it might also mean the entire construct (using "#if __STDC__"). R -- Using Opera's revolutionary email client: http://www.opera.com/mail/Ahh, I've been looking at the ANSI C spec and assuming that is what you're basing things off, K&R C was pre-ANSI C and may have different rules. I think you should probably aim to be ANSI C compliant and above, and ignore K&R.This page says otherwise: http://en.wikipedia.org/wiki/ANSI_C#Compliance_detectability "...while an obsolescent non-prototype declaration is used otherwise. Those are still ANSI-compliant as of C99 and C90, but their use is discouraged".
Jul 18 2012
In any case. It think the practical solution to this problem is to assume you're working with modern code, and have a command line option to make it assume K&R or old-style declarations. In the old-style mode you would have to assume a function with an empty () could have any number of parameters and the best you can do is produce: extern (C) <ret> <name>(/* fill in the blanks please*/); R
Jul 18 2012
On 2012-07-18 12:25, Regan Heath wrote:In any case. It think the practical solution to this problem is to assume you're working with modern code, and have a command line option to make it assume K&R or old-style declarations. In the old-style mode you would have to assume a function with an empty () could have any number of parameters and the best you can do is produce: extern (C) <ret> <name>(/* fill in the blanks please*/); RSeems like this will be the solution. -- /Jacob Carlborg
Jul 18 2012
On Tue, 17 Jul 2012 15:46:34 +0100, Jacob Carlborg <doob me.com> wrote:On 2012-07-17 16:36, Regan Heath wrote:K&R C did not allow you to declare arguments at all, according to the wiki: "Since K&R function declarations did not include any information about function arguments, function parameter type checks were not performed, although some compilers would issue a warning message if a local function was called with the wrong number of arguments, or if multiple calls to an external function used different numbers or types of arguments. Separate tools such as Unix's lint utility were developed that (among other things) could check for consistency of function use across multiple source files." So all K&R function declarations were <name>() with no parameters. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/I believe old-style no parameter function declarations MUST have "void" i.e. int foo(void);That is still the case, regardless of "style"?They cannot read: int foo(); The latter MUST have parameters, we just can't tell what they are.Take a look at this: http://en.wikipedia.org/wiki/K%26R_C#KRC In that example none of the functions have any parameters declared and are not called with any arguments.
Jul 17 2012
On Tuesday, 17 July 2012 at 15:16:56 UTC, Regan Heath wrote:On Tue, 17 Jul 2012 15:46:34 +0100, Jacob Carlborg <doob me.com> wrote:K&R was more than that. I guess most old timers here will agree with me that it was not much more than glorified assembler in what concerns typing. Much of the typing C has today, was actually brought in as part of the ANSI C standardization process. -- PauloOn 2012-07-17 16:36, Regan Heath wrote:K&R C did not allow you to declare arguments at all, according to the wiki: "Since K&R function declarations did not include any information about function arguments, function parameter type checks were not performed, although some compilers would issue a warning message if a local function was called with the wrong number of arguments, or if multiple calls to an external function used different numbers or types of arguments. Separate tools such as Unix's lint utility were developed that (among other things) could check for consistency of function use across multiple source files." So all K&R function declarations were <name>() with no parameters. RI believe old-style no parameter function declarations MUST have "void" i.e. int foo(void);That is still the case, regardless of "style"?They cannot read: int foo(); The latter MUST have parameters, we just can't tell what they are.Take a look at this: http://en.wikipedia.org/wiki/K%26R_C#KRC In that example none of the functions have any parameters declared and are not called with any arguments.
Jul 17 2012
On Tue, Jul 17, 2012 at 08:07:08PM +0200, Paulo Pinto wrote:On Tuesday, 17 July 2012 at 15:16:56 UTC, Regan Heath wrote:[...]This modern C declaration: int main(int argc, char **argv) { exit(1); } is written thus in K&R: int main(argc, argv) int argc; char **argv; { exit(1); }So all K&R function declarations were <name>() with no parameters. RK&R was more than that.I guess most old timers here will agree with me that it was not much more than glorified assembler in what concerns typing.[...] I guess you predate me. ;-) When I started learning C, it was already in the ANSI syntax, though there were enough K&R style code floating around that I've at least _seen_ K&R syntax. I'm guessing nowadays most people don't even know what K&R syntax is. T -- If I were two-faced, would I be wearing this one? -- Abraham Lincoln
Jul 17 2012
Definitely - I live in a very technologically-savvy dorm in college, and when I encountered it for the first time nobody there had any idea what it was. ...we did later find an old book in our library that had it, though. -Matt On 07/17/2012 02:39 PM, H. S. Teoh wrote:On Tue, Jul 17, 2012 at 08:07:08PM +0200, Paulo Pinto wrote:On Tuesday, 17 July 2012 at 15:16:56 UTC, Regan Heath wrote:[...]This modern C declaration: int main(int argc, char **argv) { exit(1); } is written thus in K&R: int main(argc, argv) int argc; char **argv; { exit(1); }So all K&R function declarations were <name>() with no parameters. RK&R was more than that.I guess most old timers here will agree with me that it was not much more than glorified assembler in what concerns typing.[...] I guess you predate me. ;-) When I started learning C, it was already in the ANSI syntax, though there were enough K&R style code floating around that I've at least _seen_ K&R syntax. I'm guessing nowadays most people don't even know what K&R syntax is. T
Jul 17 2012
On Tuesday, 17 July 2012 at 18:37:54 UTC, H. S. Teoh wrote:I guess you predate me. ;-) When I started learning C, it was already in the ANSI syntax, though there were enough K&R style code floating around that I've at least _seen_ K&R syntax. I'm guessing nowadays most people don't even know what K&R syntax is. TI started coding in C around 1993 with Turbo C 2.0, but was exposed to K&R code from different sources, specially when we needed to make use of a System V based system for some OS classes. Plus as a language geek, I had the pleasure to have access a lots of books and papers since the late 70's in our university library. That is a reason why I tend to have a good background in what languages introduced which paradigm. Maybe it is the historian in me. :) -- Paulo
Jul 17 2012
On Tue, 17 Jul 2012 19:39:25 +0100, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:On Tue, Jul 17, 2012 at 08:07:08PM +0200, Paulo Pinto wrote:Clarification. The /definition/ is as you have above, the /declaration/ is not. The declaration is what goes in the header file, and in K&R (and ANSI C for that matter) looks like: int main(); parameters are not required for the declaration, only the definition. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/On Tuesday, 17 July 2012 at 15:16:56 UTC, Regan Heath wrote:[...]This modern C declaration: int main(int argc, char **argv) { exit(1); } is written thus in K&R: int main(argc, argv) int argc; char **argv; { exit(1); }So all K&R function declarations were <name>() with no parameters. RK&R was more than that.
Jul 18 2012
On Wed, Jul 18, 2012 at 11:23:33AM +0100, Regan Heath wrote:On Tue, 17 Jul 2012 19:39:25 +0100, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:[...][...] You are right. And also, under K&R syntax, the 'int' can be omitted from before main. I *think* the entire argc line can be omitted as well (undeclared variables default to int, IIRC). 'Tis a strange world they used to live in. :-) T -- Almost all proofs have bugs, but almost all theorems are true. -- Paul PedersenThis modern C declaration: int main(int argc, char **argv) { exit(1); } is written thus in K&R: int main(argc, argv) int argc; char **argv; { exit(1); }Clarification. The /definition/ is as you have above, the /declaration/ is not. The declaration is what goes in the header file, and in K&R (and ANSI C for that matter) looks like: int main(); parameters are not required for the declaration, only the definition.
Jul 18 2012
On 2012-07-17 14:32, Regan Heath wrote:After a bit of googling and a test with my local MSVC9 I think old-style variadics look like this: #include <varargs.h> #include <stdio.h> void foo(va_alist) va_dcl { va_list p; va_start(p); vprintf("%d %d %d\n", p); } void main() { foo(1, 2, 3); } (the above runs and outputs "1 2 3" on the console) The same syntax is/was supported by GNU C, see: http://ftp.gnu.org/old-gnu/Manuals/glibc-2.2.3/html_chapter/libc_34.html#SEC676 I believe, if you see an "old-style" function declaration in a header file like: int foo (); that you can't actually assume anything about it's parameters, it may have /any/ number of parameters, and may or may not be variadic.Clang seems to interpret it as a variadic function. Then if that is correct or not I don't know. -- /Jacob Carlborg
Jul 17 2012
On Tue, 17 Jul 2012 15:02:44 +0100, Jacob Carlborg <doob me.com> wrote:On 2012-07-17 14:32, Regan Heath wrote:All my googling for "old style" "variadic" etc returned the use of va_alist and va_dcl so I can't see where/why Clang would do what it's doing. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/After a bit of googling and a test with my local MSVC9 I think old-style variadics look like this: #include <varargs.h> #include <stdio.h> void foo(va_alist) va_dcl { va_list p; va_start(p); vprintf("%d %d %d\n", p); } void main() { foo(1, 2, 3); } (the above runs and outputs "1 2 3" on the console) The same syntax is/was supported by GNU C, see: http://ftp.gnu.org/old-gnu/Manuals/glibc-2.2.3/html_chapter/libc_34.html#SEC676 I believe, if you see an "old-style" function declaration in a header file like: int foo (); that you can't actually assume anything about it's parameters, it may have /any/ number of parameters, and may or may not be variadic.Clang seems to interpret it as a variadic function. Then if that is correct or not I don't know.
Jul 17 2012
On 2012-07-17 16:37, Regan Heath wrote:All my googling for "old style" "variadic" etc returned the use of va_alist and va_dcl so I can't see where/why Clang would do what it's doing.To be accurate it's the libclang function "clang_isFunctionTypeVariadic" that returns true. http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga343b2463b0ed b259739242cf26c3ae2 -- /Jacob Carlborg
Jul 17 2012
On Tue, 17 Jul 2012 15:50:27 +0100, Jacob Carlborg <doob me.com> wrote:On 2012-07-17 16:37, Regan Heath wrote:Is Clang open source, can we see the code for that function? Perhaps it's a bug.. ANSI C may have made () without "void" obsolete, but no compiler I've ever used has actually enforced that - or perhaps C++ made old-style function definition/declarations obsolete and allowed () back again. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/All my googling for "old style" "variadic" etc returned the use of va_alist and va_dcl so I can't see where/why Clang would do what it's doing.To be accurate it's the libclang function "clang_isFunctionTypeVariadic" that returns true. http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga343b2463b0ed4b259739242cf26c3ae2
Jul 17 2012
On Tuesday, 17 July 2012 at 15:13:52 UTC, Regan Heath wrote:On Tue, 17 Jul 2012 15:50:27 +0100, Jacob Carlborg <doob me.com> wrote:In C++, a function with no parameters () is a synonym for (void). -- PauloOn 2012-07-17 16:37, Regan Heath wrote:Is Clang open source, can we see the code for that function? Perhaps it's a bug.. ANSI C may have made () without "void" obsolete, but no compiler I've ever used has actually enforced that - or perhaps C++ made old-style function definition/declarations obsolete and allowed () back again. RAll my googling for "old style" "variadic" etc returned the use of va_alist and va_dcl so I can't see where/why Clang would do what it's doing.To be accurate it's the libclang function "clang_isFunctionTypeVariadic" that returns true. http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga343b2463b0ed4b259739242cf26c3ae2
Jul 17 2012
On Tue, 17 Jul 2012 19:08:51 +0100, Paulo Pinto <pjmlp progtools.org> wrote:On Tuesday, 17 July 2012 at 15:13:52 UTC, Regan Heath wrote:That's what I've been assuming all this time, but I wasn't sure if I was technically (according to the spec) right, so I didn't want to say.. :) R -- Using Opera's revolutionary email client: http://www.opera.com/mail/On Tue, 17 Jul 2012 15:50:27 +0100, Jacob Carlborg <doob me.com> wrote:In C++, a function with no parameters () is a synonym for (void).On 2012-07-17 16:37, Regan Heath wrote:Is Clang open source, can we see the code for that function? Perhaps it's a bug.. ANSI C may have made () without "void" obsolete, but no compiler I've ever used has actually enforced that - or perhaps C++ made old-style function definition/declarations obsolete and allowed () back again. RAll my googling for "old style" "variadic" etc returned the use of va_alist and va_dcl so I can't see where/why Clang would do what it's doing.To be accurate it's the libclang function "clang_isFunctionTypeVariadic" that returns true. http://clang.llvm.org/doxygen/group__CINDEX__TYPES.html#ga343b2463b0ed4b259739242cf26c3ae2
Jul 18 2012
On 2012-07-17 17:13, Regan Heath wrote:Is Clang open source, can we see the code for that function? Perhaps it's a bug.. ANSI C may have made () without "void" obsolete, but no compiler I've ever used has actually enforced that - or perhaps C++ made old-style function definition/declarations obsolete and allowed () back again.Sure: https://llvm.org/svn/llvm-project/cfe/trunk/tools/libclang/CXType.cpp Just search for clang_isFunctionTypeVariadic. -- /Jacob Carlborg
Jul 17 2012
On Tue, 17 Jul 2012 20:42:09 +0100, Jacob Carlborg <doob me.com> wrote:On 2012-07-17 17:13, Regan Heath wrote:It certainly seems intentional: if (T->getAs<FunctionNoProtoType>()) return 1; I wonder if it's a case of "we can't be certain, so lets assume it is" or similar. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/Is Clang open source, can we see the code for that function? Perhaps it's a bug.. ANSI C may have made () without "void" obsolete, but no compiler I've ever used has actually enforced that - or perhaps C++ made old-style function definition/declarations obsolete and allowed () back again.Sure: https://llvm.org/svn/llvm-project/cfe/trunk/tools/libclang/CXType.cpp Just search for clang_isFunctionTypeVariadic.
Jul 18 2012
On 17/07/2012 08:56, Jacob Carlborg wrote:To my understanding this is legal C : int foo (); It's a K&R-style variadic functions, while their use is discouraged, they're still legal C. If I, in D, declare a variadic function with C linkage that doesn't take, at least, one regular parameter the compiler will complain. extern (C) int foo (...);It is used in testfptr.d from dmd's testsuite.
Jul 17 2012
"deadalnix" <deadalnix gmail.com> wrote in message news:ju3uqc$55g$1 digitalmars.com...It is used in testfptr.d from dmd's testsuite.No, that's a D-linkage variadic.
Jul 17 2012
I was sure that if function is declared with empty () than you can call it with any arguments you imagine, as it is in following examples. ============================= ex. 1 <*> cat main.c void a() { } int main() { a(1, 2, 3); return 0; } <*> gcc -Wall -Wextra -pedantic main.c <*> ============================== ex. 2 <*> cat test.c #include <stdio.h> void a(int a, char b, void* ptr) { printf("%d %c %p\n", a, b, ptr); } <*> cat main.c extern void a(); int main() { int aa = 123; void* ptr = (void*)0xffaaffaa; a(aa, b, ptr); return 0; } <*> gcc -c test.c <*> gcc -c main.c <*> gcc -o main main.o test.o <*> ./main <*> But this is not:
Jul 17 2012
On 7/16/2012 11:56 PM, Jacob Carlborg wrote:To my understanding this is legal C : int foo (); It's a K&R-style variadic functions, while their use is discouraged, they're still legal C.Variadic functions, in order to work in C, need at least one parameter so that varargs can work. int foo(); declares a function with an unspecified parameter list, not a variadic one. It is specified by a definition somewhere: int foo(a,b) int a; int b; { ... } somewhere. If Dstep encounters the first declaration form, your options are to: 1. reject it (a perfectly reasonable approach) 2. treat it as: int foo(void); I suggest option 2, which is what C++ does.
Jul 18 2012
On 2012-07-18 11:41, Walter Bright wrote:Variadic functions, in order to work in C, need at least one parameter so that varargs can work. int foo(); declares a function with an unspecified parameter list, not a variadic one. It is specified by a definition somewhere: int foo(a,b) int a; int b; { ... } somewhere.I think I understand now.If Dstep encounters the first declaration form, your options are to: 1. reject it (a perfectly reasonable approach) 2. treat it as: int foo(void); I suggest option 2, which is what C++ does.Sounds reasonable. I will also provide a flag specifying how this should be handled. I actually found library that uses this style of declaration. It's used in several places in libruby. For example: void rb_define_virtual_variable(const char*,VALUE(*)(ANYARGS),void(*)(ANYARGS)); ANYARGS is defined as: #ifdef __cplusplus #define ANYARGS ... #else #define ANYARGS #endif Does that mean that this C++ declaration: void foo (...); Is the same as this C declaration? void foo (); I'm wondering if the intention is to cast these function pointers to their correct signature before calling them. -- /Jacob Carlborg
Jul 18 2012
On 7/18/2012 4:59 AM, Jacob Carlborg wrote:Does that mean that this C++ declaration: void foo (...);Not allowed in C or C++.Is the same as this C declaration? void foo ();That is void foo(void) in C++.
Jul 18 2012
On 2012-07-18 20:43, Walter Bright wrote:On 7/18/2012 4:59 AM, Jacob Carlborg wrote:When compiling in C++ mode, both Clang and GCC accepts this.Does that mean that this C++ declaration: void foo (...);Not allowed in C or C++.-- /Jacob CarlborgIs the same as this C declaration? void foo ();That is void foo(void) in C++.
Jul 18 2012
On 7/18/2012 11:47 AM, Jacob Carlborg wrote:On 2012-07-18 20:43, Walter Bright wrote:How would you get the arguments inside foo?On 7/18/2012 4:59 AM, Jacob Carlborg wrote:When compiling in C++ mode, both Clang and GCC accepts this.Does that mean that this C++ declaration: void foo (...);Not allowed in C or C++.
Jul 18 2012
On 2012-07-18 22:12, Walter Bright wrote:How would you get the arguments inside foo?I don't know, you're the compiler writer :) I don't know these kind of things, that's why I started this thread. I'm just telling you how GCC/Clang treats these code snippets. -- /Jacob Carlborg
Jul 18 2012
On Wednesday, 18 July 2012 at 20:13:10 UTC, Walter Bright wrote:On 7/18/2012 11:47 AM, Jacob Carlborg wrote:As described here, http://pubs.opengroup.org/onlinepubs/7908799/xsh/varargs.h.htmlOn 2012-07-18 20:43, Walter Bright wrote:How would you get the arguments inside foo?On 7/18/2012 4:59 AM, Jacob Carlborg wrote:When compiling in C++ mode, both Clang and GCC accepts this.Does that mean that this C++ declaration: void foo (...);Not allowed in C or C++.
Jul 19 2012
On Thu, 19 Jul 2012 08:33:12 +0100, Paulo Pinto <pjmlp progtools.org> wrote:On Wednesday, 18 July 2012 at 20:13:10 UTC, Walter Bright wrote:That /requires/ an argument in the definition (AFAIKS), e.g. execl(va_alist) <- va_alist is the argument name va_dcl <- this is #define va_dcl va_list va_alist; { } so, it's no different to any other old-style function, e.g. foo(a) int a; { } Now.. the declaration may be a different story. These would be valid declarations for the above: void execl(); <- no parameters necessary in a declaration void foo(); <- no parameters necessary in a declaration It may be that GCC allows a declaration of: void execl(...); But I wasn't ware that was valid ANSI C, perhaps it's a GCC/clang feature? Can anyone find docs on it? If we /assume/ the above declaration always refers to a function with a definition of: execl(va_alist) va_dcl { } Then we assume the first argument is /always/ going to be a 32 bit value (int, or 32 bit pointer) then we could speculatively convert to this D extern (C) void execl(int first, ...); But, if either assumption is false this would probably crash when used. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/On 7/18/2012 11:47 AM, Jacob Carlborg wrote:As described here, http://pubs.opengroup.org/onlinepubs/7908799/xsh/varargs.h.htmlOn 2012-07-18 20:43, Walter Bright wrote:How would you get the arguments inside foo?On 7/18/2012 4:59 AM, Jacob Carlborg wrote:When compiling in C++ mode, both Clang and GCC accepts this.Does that mean that this C++ declaration: void foo (...);Not allowed in C or C++.
Jul 19 2012
On 2012-07-19 11:38, Regan Heath wrote: asn't ware that was valid ANSI C, perhaps it's a GCC/clangfeature? Can anyone find docs on it?Note that it only works when compiling as C++. Perhaps it works like this: If C++ is interpreting this: void foo (); As: void foo (void); Perhaps it will interpret: void foo (...); As C would interpret this: void foo (); -- /Jacob Carlborg
Jul 19 2012