July 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


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


July 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;
    char b = '#';
    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
123  #  0xffaaffaa
<*>

But this is not:

July 18, 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:
> [...]
>>> So all K&R function declarations were <name>() with no parameters.
>>>
>>> R
>>
>> K&R was more than that.
>
> 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);
> 	}
>
>
>> 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
>

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

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

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

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/
July 18, 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:
>> On Tuesday, 17 July 2012 at 15:16:56 UTC, Regan Heath wrote:
> [...]
>> >So all K&R function declarations were <name>() with no parameters.
>> >
>> >R
>>
>> K&R was more than that.
>
> 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.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
July 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
July 18, 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:
>> On Tue, 17 Jul 2012 15:50:27 +0100, Jacob Carlborg <doob@me.com> wrote:
>>
>>> 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#ga343b2463b0ed4b259739242cf26c3ae2
>>
>> 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
>
> In C++, a function with no parameters () is a synonym for (void).

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/