July 18, 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:
>
>> 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.

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/
July 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*/);
>
> R

Seems like this will be the solution.

-- 
/Jacob Carlborg


July 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


July 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:
[...]
> >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);
> >	}
> 
> 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.
[...]

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 Pedersen
July 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++.



July 18, 2012
On 2012-07-18 20:43, Walter Bright wrote:
> 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++.

When compiling in C++ mode, both Clang and GCC accepts this.

>> Is the same as this C declaration?
>>
>> void foo ();
>
> That is void foo(void) in C++.

-- 
/Jacob Carlborg


July 18, 2012
On 7/18/2012 11:47 AM, Jacob Carlborg wrote:
> On 2012-07-18 20:43, Walter Bright wrote:
>> 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++.
>
> When compiling in C++ mode, both Clang and GCC accepts this.

How would you get the arguments inside foo?


July 19, 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


July 19, 2012
On Wednesday, 18 July 2012 at 20:13:10 UTC, Walter Bright wrote:
> On 7/18/2012 11:47 AM, Jacob Carlborg wrote:
>> On 2012-07-18 20:43, Walter Bright wrote:
>>> 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++.
>>
>> When compiling in C++ mode, both Clang and GCC accepts this.
>
> How would you get the arguments inside foo?

As described here,

http://pubs.opengroup.org/onlinepubs/7908799/xsh/varargs.h.html
July 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:
>> On 7/18/2012 11:47 AM, Jacob Carlborg wrote:
>>> On 2012-07-18 20:43, Walter Bright wrote:
>>>> 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++.
>>>
>>> When compiling in C++ mode, both Clang and GCC accepts this.
>>
>> How would you get the arguments inside foo?
>
> As described here,
>
> http://pubs.opengroup.org/onlinepubs/7908799/xsh/varargs.h.html

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/