www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 11881] New: -betterC switch suffers from bit rot

reply d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881

           Summary: -betterC switch suffers from bit rot
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: bugzilla digitalmars.com



18:57:47 PST ---
Adam D. Ruppe writes:

I find the -betterC switch to be totally useless. If you are just toying,
there's no module info anyway:

extern(C) {
    void _d_run_main() {} // why is this required now????
    void* _d_dso_registry;

    void _start() {

    }
}

dmd -c *.d -defaultlib= -debuglib=
gcc -m32 *.o -nostdlib

success. Add "struct Test{}" and:

Error: ModuleInfo not found. object.d may be incorrectly installed or corrupt.

OK, add -betterC:

Error: TypeInfo not found. object.d may be incorrectly installed or corrupt,
compile with -v switch


If you do use an object.d with it defined to get past the compiler, it doesn't
help much as the linker complains anyway:

test.o:(.data._D20TypeInfo_S4test4Test6__initZ+0x0): undefined reference to
`_D15TypeInfo_Struct6__vtblZ'


So my verdict is -betterC is pretty useless. If it got past the TypeInfo stuff
the same way it gets past ModuleInfo though, then we'd be cooking with gas.
That potentially gives a language that is legitimately a better C. But without
structs, bah.

This is a filthy hack, but it is easy to change this in the compiler. (Isn't
-betterC a filthy hack in the first place anyway :) )

In

Expression *Type::getTypeInfo(Scope *sc)

Add
    if(global.params.betterC)
        return NULL;

right to the top.

And same for struct decl

void TypeInfoStructDeclaration::toDt(dt_t **pdt)
{
    if(global.params.betterC)
        return;


Then it compiles with the struct! ~5 KB executable, two line object.d.


....but adding some methods to the struct complain about missing ModuleInfo
again. Looks like it wants to do assert(this !is null); and the assert thing
takes a module info reference.

Ugh.... that said, adding:

    void _d_assert_msg() {}
    void _d_assertm() {}
    void* _D4test12__ModuleInfoZ;

to my extern(C) boilerplate did manage to work - structs with postblits and
dtors yay! - and trimmed the exe down to 1.3K.

Maybe -betterC can stop outputting those references too and then we'd really be
cooking.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 07 2014
next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881


Adam D. Ruppe <destructionator gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |destructionator gmail.com



19:27:21 PST ---
Other stuff I think this should do:

* suppress the generation of the call _d_dso_registry function
(backend/elfobj.c).

* The assert isn't put out with -release, but that kills all asserts. So I
think -betterC might be good to suppress any *hidden* asserts, while keeping
explicit ones in (which are removed with -release if you want to kill them
too). The struct method calling _d_assertm, which requires ModuleInfo, is a
hidden assert on the struct method.

actually that just might do the trick for a better c. Toying with these, I made
a test.d with an extern(C) main and it worked fairly well. My hacky changes to
the compiler caused it to crash if I tried to use a class, but C doesn't have
classes either so oh well.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 07 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881





 * The assert isn't put out with -release, but that kills all asserts. So I
 think -betterC might be good to suppress any *hidden* asserts, while keeping
 explicit ones in (which are removed with -release if you want to kill them
 too). The struct method calling _d_assertm, which requires ModuleInfo, is a
 hidden assert on the struct method.
An idea: Under -betterC switch, "assertion failures" and "range checks" will be implemented by HLT operation. Merits of the idea are: 1. -betterC switch would merely get rid of the dependency to the runtime library. Other switches, -noboundscheck and -release, would keep their meanings. 2. Normal assert would be kept useful (condition is checked in runtime and HLT program if it fails, if needed). 3. Range check is important for SafeD concept. We should have a way to do it without runtime library. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 08 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881




Based on "remove the relation to the runtime library" concept, we can extend
-betterC switch meaning.

One more idea:
If -betterC is specified, glue layer will report error for the uses of language
feature which requires runtime library, such as:

- new expression
- typeid expression
- array literal that is allocated on heap
- AA literal
- array concatenation and appending
- closure creation

I think that we should define "minimum D" to spread the activity area of D.
Making -betterC switch more useful is necessary work.

And, this is closely related to the nogc/noheap feature.
So it would also be a good challenge for the requests.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 08 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull




 An idea:
 Under -betterC switch, "assertion failures" and "range checks" will be
 implemented by HLT operation.
https://github.com/D-Programming-Language/dmd/pull/3072 -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 08 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs eml.cc



Where is the discussion about this feature?

The name "betterC" implies a quality judgement on C and D languages, it's
subjective. A serious technical product as D should prefer to avoid such
expressions of subjectivity, so I suggest a more descriptive and neutral name.
Something like "-noruntime" perhaps?



Currently the LDC2 compiler has a -noruntime switch:

-noruntime  - Do not allow code that generates implicit runtime calls


But currently ldc2 only gives a true/false answer, it doesn't give the line
numbers where you are the runtime is used. This makes it hard to find the
spots.

A little test program:


void main() {
    int x = 1;
    assert(x);
}


Gives:


...>ldmd2 -noruntime test.d
Error: No implicit runtime calls allowed with -noruntime option enabled

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 08 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881




05:35:46 PST ---
 Under -betterC switch, "assertion failures" and "range checks" will be
 implemented by HLT operation.
I don't think that's a great idea because if you were using this in kernel mode, the hlt operation just pauses the CPU until the next interrupt, then it continues on. It doesn't kill the program and doesn't even alert the user. int 3 might be a better choice, even in kernel mode that's a debugging trap, and it is also a one byte instruction on x86 (0xCC). I'd say either do that or continue to generate a call to a runtime function, but just use _d_assert without the moduleinfo argument instead of _d_assertm. Implementing some runtime functions isn't a dealbreaker to me; we could always just add extern(C) void _d_assert() { asm { int 3; } } or whatever easily enough to the file when it is needed - we just want to avoid needing the full definitions and data for module info, typeinfo, etc., as that's where the runtime code starts to get more complicated. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 08 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881




05:46:55 PST ---
 Where is the discussion about this feature?
I don't think there ever was one, it was just an undocumented hack Walter slapped together a long time ago to make his work easier but doesn't get updated as the language changes. So we're discussing bringing it back up to date and maybe improving it a little. But in my mind at least, we're still talking about an undocumented hack so things are a bit less formal than they might normally be :) -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 08 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881




05:53:43 PST ---
 If -betterC is specified, glue layer will report error for the uses of language
 feature which requires runtime library, such as:
Hmm, maybe. But right now if you used them, you'd get a linker error about a missing function and can choose to remove the call or implement the function. So in a way, it is "pay for what you use". With a compile error, implementing it piecewise wouldn't be as easy - you'd have to drop the switch and go back to writing a druntime port. I think betterC should mean anything that works in C also works here with little to no runtime support (matches C), anything which can work without the runtime does (for example, scope statements, this makes it a better C), and the rest can just continue to be a linker error so you opt in as you want by implementing the functions. This would also be the least work to implement in the compiler, since it is leaving most things the way they are now. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 08 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881


yebblies <yebblies gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yebblies gmail.com




 int 3 might be a better choice, even in kernel mode that's a debugging trap,
 and it is also a one byte instruction on x86 (0xCC). I'd say either do that or
 continue to generate a call to a runtime function, but just use _d_assert
 without the moduleinfo argument instead of _d_assertm.
 
I think still calling _d_assertm is a good idea. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 08 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881




06:13:06 PST ---

 I think still calling _d_assertm is a good idea.
Passing it null as the ModuleInfo argument maybe? That'd work for me. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 08 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881






 I think still calling _d_assertm is a good idea.
Passing it null as the ModuleInfo argument maybe? That'd work for me.
Whoops, I meant _d_assert. _d_assertm should be destroyed. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 08 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881




06:34:35 PST ---

 Whoops, I meant _d_assert.  _d_assertm should be destroyed.
cool, I agree. Why is _d_assertm a separate function anyway? Even in the regular runtime it seems to be unnecessary. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 08 2014
prev sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=11881


Johannes Pfau <johannespfau gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |johannespfau gmail.com



PST ---
 bearophile we discussed -fstandalone for gdc some time ago, maybe that's a
better name?

I think we should try to avoid TypeInfo whenever possbile, so +1 for removing
_d_assertm.

Long-term 
* _d_newclass should probably be replaced with a templated version.
* Array and associative arrays should probably be replaced with templates 
  (keeping the compiler magic, but using template internally instead of RTTI)

 Adam

I'd say we introduce a core/config.di file with this content:
------------------
enum RUNTIME_SUPPORTS_RTTI = false;
enum RUNTIME_SUPPORTS_UTF_FOREACH = false; /*forach(dchar x; "utf8")*/ 
enum RUNTIME_SUPPORTS_GC = false
------------------

If core/config.di isn't found the compiler automatically assumes false for all
flags, i.e. a minimal runtime.

The benefits of creating config.di instead of adding it to dmd.conf:
* Works for GDC (no config file)
* Works fine if you have multiple runtimes with different feature sets.
  Just change the include and link path and the compiler information about
  RUNTIME_SUPPORTS_RTTI etc always matches the exact runtime.
* Point 2 above might be interesting for GCC multilib configurations (you could 
  have one compiler which uses -mdminimal -mdnormal to select between different
  runtimes and automatically adjust the link paths. Exactly like -m32 and -m64 
  is implemented in GCC right now)

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