Bug 846 – Error 42: Symbol Undefined "<mangle_of_class_template>__arrayZ"

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2007-01-13T11:28:00Z
Last change time
2015-08-07T06:44:53Z
Keywords
link-failure, pull
Assigned to
bugzilla
Creator
sean
See also
https://issues.dlang.org/show_bug.cgi?id=14828, https://issues.dlang.org/show_bug.cgi?id=14871

Comments

Comment #0 by sean — 2007-01-13T11:28:27Z
This is a variation of the "template library bug," similar to why std.boxer is incompatible with debug user apps. Support for in/out contracts seems to be fixed, as they always seem to be generated within the template function body, but it appears that array bounds and assertion checks are still sometimes expected to exist in the object containing the declaration of the template code. Here is an example: module a; template ElemTypeOf( T ) { alias typeof(T[0]) ElemTypeOf; } template removeIf_( Elem, Pred ) { size_t fn( Elem[] buf, Pred pred ) { void exch( size_t p1, size_t p2 ) { Elem t = buf[p1]; buf[p1] = buf[p2]; buf[p2] = t; } size_t cnt = 0; for( size_t pos = 0, len = buf.length; pos < len; ++pos ) { if( pred( buf[pos] ) ) ++cnt; else exch( pos, pos - cnt ); } return buf.length - cnt; } } template removeIf( Buf, Pred ) { size_t removeIf( Buf buf, Pred pred ) { return removeIf_!(ElemTypeOf!(Buf), Pred).fn( buf, pred ); } } ---------- import a; void main() { auto num = removeIf( "abcdef".dup, ( char c ) { return c == 'c'; } ); } C:\code\src\d\test>dmd b c:\bin\dmd\bin\..\..\dm\bin\link.exe b,,,user32+kernel32/noi; OPTLINK (R) for Win32 Release 7.50B1 Copyright (C) Digital Mars 1989 - 2001 All Rights Reserved b.obj(b) Error 42: Symbol Undefined _D1a7__arrayZ --- errorlevel 1 It appears that whether this error occurs may somehow be related to the inlining mechanism, because I have some template functions that exhibit this behavior and others that do not. This bug is a major obstacle to building libraries containing template code in D, particularly when the user cannot manually link a debug library because the library name is selected automatically (as with phobos.lib). Also, I don't entirely understand why a separate bound-check and assert function must apparently be generated for every module, since the contents should be immutable. The easiest fix for std.boxer (if perhaps not user libraries) would be to link separate standard libraries for debug and release builds--phobos.lib vs. phobosd.lib, for example. But it would be far preferable if code generation could be fixed such that this problem no longer occurs.
Comment #1 by sean — 2007-01-23T13:09:49Z
This is related to issue 8.
Comment #2 by bugzilla — 2007-01-31T03:41:45Z
The problem is that the __array() function is not generated for module a if it is compiled with -release. I'll fix it so it does, but to get the example to work, you'll still need to link with a.obj.
Comment #3 by sean — 2007-01-31T11:50:29Z
[email protected] wrote: > > The problem is that the __array() function is not generated for module a if it > is compiled with -release. I'll fix it so it does, but to get the example to > work, you'll still need to link with a.obj. That's fine. My only concern is that template code in release libraries be usable in debug applications (since non-template code is). The only remaining issues seem to be _array() and _assert() (and possibly not _assert()--I haven't found a case where this breaks yet), and always building it/them into the module should address this.
Comment #4 by bugzilla — 2007-02-12T03:39:18Z
Fixed DMD 1.005
Comment #5 by ultimate.macfan.atic — 2008-11-03T04:40:46Z
I'm getting linking errors when I compile and link a module I wrote using dmd that sound similar to what's described here. I've looked for other documentation of this issue, but I haven't found any so I'm going to go ahead and post this as a bug to see if anyone else can replicate it, even though this problem appears to have been fixed the last time it was rearing its (insert creative adjective here) head. The error output: C:\Documents and Settings\Christopher Johnson\My Documents>dmd -v edu\utah\eng\chjohnso\boggle.d parse boggle semantic boggle import object (\dmd\src\phobos\object.d) import std.c.stdlib (\dmd\src\phobos\std\c\stdlib.d) import std.c.stddef (\dmd\src\phobos\std\c\stddef.d) import std.ctype (\dmd\src\phobos\std\ctype.d) import edu.utah.eng.chjohnso.set (edu\utah\eng\chjohnso\set.d) import std.stdio (\dmd\src\phobos\std\stdio.d) import std.c.stdio (\dmd\src\phobos\std\c\stdio.d) import std.c.stdarg (\dmd\src\phobos\std\c\stdarg.d) import std.format (\dmd\src\phobos\std\format.d) import std.stdarg (\dmd\src\phobos\std\stdarg.d) import std.utf (\dmd\src\phobos\std\utf.d) import std.contracts (\dmd\src\phobos\std\contracts.d) import std.conv (\dmd\src\phobos\std\conv.d) import std.string (\dmd\src\phobos\std\string.d) import std.algorithm (\dmd\src\phobos\std\algorithm.d) import std.math (\dmd\src\phobos\std\math.d) import std.c.math (\dmd\src\phobos\std\c\math.d) import std.traits (\dmd\src\phobos\std\traits.d) import std.typetuple (\dmd\src\phobos\std\typetuple.d) import std.date (\dmd\src\phobos\std\date.d) import std.dateparse (\dmd\src\phobos\std\dateparse.d) import std.c.windows.windows (\dmd\src\phobos\std\c\windows\windows.d) import std.functional (\dmd\src\phobos\std\functional.d) import std.typecons (\dmd\src\phobos\std\typecons.d) import std.metastrings (\dmd\src\phobos\std\metastrings.d) import std.iterator (\dmd\src\phobos\std\iterator.d) import std.c.string (\dmd\src\phobos\std\c\string.d) import std.encoding (\dmd\src\phobos\std\encoding.d) import std.uni (\dmd\src\phobos\std\uni.d) import std.array (\dmd\src\phobos\std\array.d) import std.system (\dmd\src\phobos\std\system.d) import std.bitmanip (\dmd\src\phobos\std\bitmanip.d) import std.intrinsic (\dmd\src\phobos\std\intrinsic.d) import std.gc (\dmd\src\phobos\std\gc.d) import gcstats (\dmd\src\phobos\gcstats.d) import std.file (\dmd\src\phobos\std\file.d) import std.path (\dmd\src\phobos\std\path.d) import std.regexp (\dmd\src\phobos\std\regexp.d) import std.outbuffer (\dmd\src\phobos\std\outbuffer.d) import std.windows.syserror (\dmd\src\phobos\std\windows\syserror.d) import std.windows.charset (\dmd\src\phobos\std\windows\charset.d) semantic2 boggle semantic3 boggle code boggle function this function chooseChar function randomize function getFace function playWord function getScore function __foreachbody21 function _makeSetConditionary function __foreachbody22 function allLegalWordsPlayed function __dgliteral1 function allSharedLegalWordsPlayed function __dgliteral2 function allIllegalWordsPlayed function __dgliteral3 function scoreByLength function isLegal function verify function this function empty function length function insert function erase function clear function swap function opIn_r function opApply function main \dm\bin\link.exe boggle,,,user32+kernel32/noi; OPTLINK (R) for Win32 Release 8.00.1 Copyright (C) Digital Mars 1989-2004 All rights reserved. boggle.obj(boggle) Error 42: Symbol Undefined _D3edu4utah3eng8chjohnso3set7__arrayZ --- errorlevel 1 This link failure persists when I add the "-debug" switch, but goes away if I add the "-release" switch. So thankfully in the meantime there is some kind of work-around so I can at least get my code to *run*, but not being able to compile with -debug or without the extra baggage of -release sounds like it's an issue that could use some improvement both for saving keystrokes at the command-line as well as for optimal debugging. Hope I'm doing this in proper procedure! :-) Should my email not make it into this otherwise, it's [email protected] (and your Mac Fanatic only compiles D on windows because he can't get any D 2.0 compilers for his Mac OS X 10.5 :-P).
Comment #6 by bus_dbugzilla — 2012-01-16T18:42:58Z
This painful issue still exists in 2.057. Here's a simpler testcase for linux (tested on 32bit): testa.d: ---------------------------- import testb; void main() { string output; bar!(output)(); } ---------------------------- testb.d ---------------------------- struct Foo(alias al) { int[] var; int func() { return var[0]; } } void bar(alias al)() { auto foo = Foo!(al)(); } ---------------------------- $dmd testa.d testb.d testa.o: In function `_D5testa4mainFZv37__T3FooS26_D5testa4mainFZv6outputAyaZ3Foo4funcMFZi': testb.d:(.text._D5testa4mainFZv37__T3FooS26_D5testa4mainFZv6outputAyaZ3Foo4funcMFZi+0x3c): undefined reference to `_D5testa7__arrayZ' collect2: ld returned 1 exit status --- errorlevel 1 The bug goes away if you compile with "-release", or (interestingly) if you compile separately and then link. The testcase above doesn't trigger the bug on Windows, but the problem *does* exist on Windows too (I just don't have a reduced Windows test case right now).
Comment #7 by bus_dbugzilla — 2012-01-16T18:55:12Z
Increasing severity since there's no clear workaround for non-release builds.
Comment #8 by kekeniro2 — 2012-02-20T21:18:43Z
(In reply to comment #6) > $dmd testa.d testb.d I reproduced it in Windows, with -g option. dmd -g testa.d testb.d and this works. ( b,a ) dmd -g testb.d testa.d
Comment #9 by github-bugzilla — 2014-05-17T16:17:51Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/6d1882663b51dd72edeb62d78f2b23739713c3d5 fix Issue 846 - Error 42: Symbol Undefined "<mangle_of_class_template>__arrayZ" Stop using ModuleInfo for assertion and array bounds check. Instead pass filename to `_d_assert`, `_d_unittest`, and `_d_arraybounds`. https://github.com/D-Programming-Language/dmd/commit/40be370bf0ac5546a582760d046130ee570e1327 Merge pull request #3552 from 9rnsr/fix846 Issue 846 - Error 42: Symbol Undefined "<mangle_of_class_template>__arrayZ"
Comment #10 by k.hara.pg — 2014-05-17T16:23:18Z
Comment #11 by bugzilla — 2015-08-04T06:15:53Z
Comment #12 by bugzilla — 2015-08-04T20:39:08Z
(In reply to Walter Bright from comment #11) > Different fix: https://github.com/D-Programming-Language/dmd/pull/4859 This fix also means that one will have to link with an import's object file if there are references to the helper functions. The fix always generates the helper functions for a module, regardless of the compiler switch settings.