Thread overview
[Issue 3605] New: Compiler accepts invalid variable declaration, which does not link
Dec 11, 2009
Michal Minich
Dec 11, 2009
Michal Minich
Dec 11, 2009
Michal Minich
December 11, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3605

           Summary: Compiler accepts invalid variable declaration, which
                    does not link
           Product: D
           Version: 2.036
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: michal.minich@gmail.com


--- Comment #0 from Michal Minich <michal.minich@gmail.com> 2009-12-11 02:55:08 PST ---
1. struct, class and union type: Error 42: Symbol Undefined _D4main4mainFZv1sMFZS4main2S2

struct S { int x; }
void main ()
{
   S s();  // braces should not be allowed.
   s.x = 1; // comment this line and example compiles and runs
}


2. int type: Error 42: Symbol Undefined _D4main4mainFZv1iMFZi

void main ()
{
    int i(); // braces should not be allowed.
    int a = i.max; // surprisingly this and next line works.
    writeln (a);
    //i = 1; // uncomment this to cause error
    //writeln (i); // or this
}


2b. this example works correctly – compiler gives some error message, even if
not so appropriate.
Error: function main.main.i () is not callable using argument types (int)
Error: expected 0 arguments, not 1 for non-variadic function type int()

void main ()
{
    int i();
    i = 1;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 11, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3605



--- Comment #1 from Michal Minich <michal.minich@gmail.com> 2009-12-11 02:59:28 PST ---
Correction: in example 2 "i = 1;" will not cause error, only "writeln (i);"
causes it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 11, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3605


Lars T. Kyllingstad <bugzilla@kyllingen.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@kyllingen.net


--- Comment #2 from Lars T. Kyllingstad <bugzilla@kyllingen.net> 2009-12-11 03:20:09 PST ---
This is expected and well-defined behaviour. I'll explain:


(In reply to comment #0)
> 1. struct, class and union type: Error 42: Symbol Undefined _D4main4mainFZv1sMFZS4main2S2
> 
> struct S { int x; }
> void main ()
> {

Here you declare a function s() which returns an S, without the function body. The linker will expect to find it in some library or object file.

>    S s();  // braces should not be allowed.
>    s.x = 1; // comment this line and example compiles and runs
> }
> 
> 
> 2. int type: Error 42: Symbol Undefined _D4main4mainFZv1iMFZi
> 
> void main ()
> {
>     int i(); // braces should not be allowed.

Same here, the compiler assumes that the function i() will be linked in later, and therefore accepts it. The next line works because of the property syntax for calling functions. Writing i.max is equivalent to writing i().max. The property max is available for all ints.

>     int a = i.max; // surprisingly this and next line works.
>     writeln (a);

The next line also works because of the property syntax. Writing i=1 is
equivalent to writing i(1).

>     //i = 1; // uncomment this to cause error
>     //writeln (i); // or this
> }
> 
> 
> 2b. this example works correctly – compiler gives some error message, even if
> not so appropriate.
> Error: function main.main.i () is not callable using argument types (int)
> Error: expected 0 arguments, not 1 for non-variadic function type int()

This is because the compiler interprets i=1 as i(1), which doesn't work since
you have declared i() without any parameters.

> void main ()
> {
>     int i();
>     i = 1;
> }


Note that this confusing stuff will most likely disappear in the near future, as property functions will have to be annotated with the @property attribute.

  void foo(int i);
  foo = 123;           // won't work, must write foo(123)

  @property void bar(int i);
  bar = 123;           // that's more like it

You can read about it in the spec, but note again that @property isn't yet REQUIRED for this to work:

  http://www.digitalmars.com/d/2.0/function.html#property-functions

-Lars

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 11, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3605



--- Comment #3 from Lars T. Kyllingstad <bugzilla@kyllingen.net> 2009-12-11 03:37:30 PST ---
I will would like to say though, that it shouldn't be possible to declare functions like this in D. With the module system, I can't see any practical way of defining a function in a separate .d file, as its name will be mangled with the module name. Here's an example:

x.d:
   import std.stdio;
   void print(int i) { writeln(i); }

y.d:
  void print(int);
  void main() { print(123); }

$ dmd -c x.d
$ dmd y.d x.o
y.o: In function `_Dmain':
y.d:(.text._Dmain+0x9): undefined reference to `_D1y5printFiZv'
collect2: ld returned 1 exit status
--- errorlevel 1

The declaration in y.d is mangled as _D1y5printFiZv, which means y.print(int),
while the object file will contain _D1x5printFiZv, or x.print(int).

-Lars

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 11, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3605



--- Comment #4 from Michal Minich <michal.minich@gmail.com> 2009-12-11 04:15:06 PST ---
Thank you for explanation Lars,

It did not occurred to me that "int i();" can be function declaration. Maybe if such declaration required extern(D) attribute, it would be more clear what's going on. I cannot imagine what is this feature intended to do… Maybe it has some use in connection with .di files…

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 11, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3605


Lars T. Kyllingstad <bugzilla@kyllingen.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID


--- Comment #5 from Lars T. Kyllingstad <bugzilla@kyllingen.net> 2009-12-11 05:54:05 PST ---
That's a good point. I'd forgotten about .di files. But still, I think it doesn't make sense to allow empty *nested* function declarations. Nested functions are only visible inside the enclosing function scope, and as such wouldn't be included in a .di file.

Anyway, that's another discussion. I'm marking this as invalid.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------