Thread overview
Linked errors with templates in several modules - stlport.zip
Jun 25, 2004
Sukit Tretriluxana
Jun 25, 2004
Sukit Tretriluxana
Jun 25, 2004
Sukit Tretriluxana
Jun 26, 2004
J C Calvarese
Jun 27, 2004
Sukit Tretriluxana
June 25, 2004
I am constantly getting link errors when trying to make the attached project. Basically when I execute the following command,

> make unittest

I am getting the following errors.

==========================
test.obj(test)
Error 42: Symbol Undefined __Class_9ArrayList19ArrayListIterator_i17ArrayListIt
erator
test.obj(test)
Error 42: Symbol Undefined _D9ArrayList19ArrayListIterator_i17ArrayListIterator
5_ctorFiAiZC9ArrayList19ArrayListIterator_i17ArrayListIterator

--- errorlevel 2
make: *** [test.exe] Error 2
===========================

I am not quite sure what I missed here and have been trying to arrange the files and their code differently but it never gets better. Could someone help me out?

From my opinion, this is like a bug in the compiler as it doesn't seem to generate the code for the iterator. So when linked, it could find where the bind the code.

Thanks,
Ed

PS. The attached is a zip file contained all the source code and a make file. you can simply type "make unittest" and should see the error. I am using 0.93 version of DMD.




June 25, 2004
Seems like the system has problems with attachment. If you cannot download the attachment, here is the code in each file + the make file.

====================================
IteratorModule.d
====================================
public interface Iterator(ValueType) {
public bool hasNext();
public ValueType next();
}

====================================
CollectionModule.d
====================================
import IteratorModule;

public interface Collection(ValueType) {

public bool add(ValueType val);
public bool addAll(.Collection!(ValueType) col);
public void clear();
public bool contains(ValueType val);
public bool containsAll(.Collection!(ValueType) col);
public bool isEmpty();
public Iterator!(ValueType) iterator();
public bool remove(ValueType val);
public bool removeAll(.Collection!(ValueType) col);
public bool retainAll(.Collection!(ValueType) col);
public int size();
public ValueType[] toArray();
public void toArray(ValueType[] array);

}

====================================
ListModule.d
====================================
import CollectionModule;

public interface List(ValueType) : Collection!(ValueType) {

public void addAt(int index, ValueType val);
public void addAllAt(int index, Collection!(ValueType) col);
public ValueType get(int index);
public int indexOf(ValueType val);
public int lasIndexOf(ValueType val);
public ValueType removeAt(int index);
public ValueType set(int index, ValueType val);
public .List!(ValueType) subList(int fromIndex, int toIndex);

}

====================================
ArrayListModule.d
====================================
import ListModule;
import IteratorModule;

public class ArrayList(ValueType) : List!(ValueType) {
private int curSize;
private ValueType[] values;
private int incExpcurSize;

public this() {
this(100, 100);
}

public this(int initCapacity) {
this(initCapacity, 100);
}

public this(int initCapacity, int incExpcurSize) {
curSize = 0;
values.length = initCapacity;
incExpcurSize = incExpcurSize;
}

public bool add(ValueType val) {
ensurecurSize(curSize + 1);
values[curSize++] = val;
return true;
}

public void addAt(int index, ValueType val) {
ensurecurSize(curSize + 1);
shiftRight(index, 1);
values[index] = val;
}

public bool addAll(Collection!(ValueType) col) {
Iterator!(ValueType) itor = col.iterator();
while(itor.hasNext()) {
add(itor.next());
}
return true;
}

public void addAllAt(int index, Collection!(ValueType) col) {
ensurecurSize(curSize + col.size);
shiftRight(index, col.size);
Iterator!(ValueType) itor = col.iterator();
for(int i = index; itor.hasNext(); ++i) {
values[i] = itor.next();
}
}

public void clear() {
curSize = 0;
}

public bool contains(ValueType val) {
return indexOf(val) != -1;
}

public bool containsAll(Collection!(ValueType) col) {
Iterator!(ValueType) itor = col.iterator();
while(itor.hasNext()) {
if(!contains(itor.next())) {
return false;
}
}
return true;
}

public bool isEmpty() {
return curSize == 0;
}

public Iterator!(ValueType) iterator() {
return new ArrayListIterator!(ValueType)(curSize, values);
// return new ArrayListIterator!(ValueType)(curSize, curSize);
}

public ValueType get(int index) {
return values[index];
}

public int indexOf(ValueType val) {
for(int i = 0; i < curSize; ++i) {
if(values[i] == val) {
return i;
}
}
return -1;
}

public int lasIndexOf(ValueType val) {
for(int i = curSize - 1; i >= 0; --i) {
if(values[i] == val) {
return i;
}
}
return -1;
}

public ValueType set(int index, ValueType val) {
ValueType oldval = values[index];
values[index] = val;
return oldval;
}

public int size() {
return curSize;
}

public List!(ValueType) subList(int fromIndex, int toIndex) {
int count = toIndex - fromIndex;
ArrayList!(ValueType) subl = new .ArrayList!(ValueType)(count);
subl.values[] = this.values[fromIndex..toIndex];
return subl;
}

public bool remove(ValueType val) {
int pos = indexOf(val);
if(pos != -1) {
shiftLeft(pos, 1);
--curSize;
return true;
}
return false;
}

public ValueType removeAt(int index) {
ValueType oldval = values[index];
shiftLeft(index, 1);
--curSize;
return oldval;
}

public bool removeAll(Collection!(ValueType) col) {
bool changed = false;
Iterator!(ValueType) itor = col.iterator();
while(itor.hasNext()) {
changed = remove(itor.next()) || changed;
}
return changed;
}

public bool retainAll(Collection!(ValueType) col) {
bool changed = false;
for(int index = 0; index < curSize; ) {
if(col.contains(values[index])) {
++index;
} else {
removeAt(index);
changed = true;
}
}
return changed;
}

public ValueType[] toArray() {
ValueType[] result = new ValueType[curSize];
result[] = values;
return result;
}

public void toArray(ValueType[] array) {
array[] = values;

}

private void ensurecurSize(int reqcurSize) {
if(reqcurSize > values.length) {
int newcurSize = reqcurSize - curSize <= incExpcurSize
? incExpcurSize : reqcurSize + incExpcurSize;
values.length = newcurSize;
}
}

private void shiftLeft(int startIndex, int offset) {
for(int index = startIndex; index < curSize; --index) {
values[index - offset] = values[index];
}
}

private void shiftRight(int startIndex, int offset) {
for(int index = curSize - 1; index < startIndex; --index) {
values[index + offset] = values[index];
}
}
}

public class ArrayListIterator(ValueType) : Iterator!(ValueType) {
private int curSize, index;
private ValueType[] data;

public this(int curSize, ValueType[] data) {
// public this(int curSize, int data) {
this.curSize = curSize;
this.data = data;
// this.curSize = data;
index = 0;
}

public bool hasNext() {
return index < curSize;
}

public ValueType next() {
return data[index++];
}
}

====================================
test.d
====================================
import ArrayListModule;

void main()
{
ArrayList!(int) iarray = new ArrayList!(int)();

}

====================================
Makefile
====================================
DMD = dmd
SRCS = \
IteratorModule.d				\
CollectionModule.d				\
ListModule.d						\
ArrayListModule.d
OBJS = $(SRCS:.d=.obj)
TEST_SRCS = test.d
TEST_OBJS = $(TEST_SRCS:.d=.obj)
LIB = stl.lib
TEST = test.exe

all: $(SRCS) $(LIB)

clean:
rm $(OBJS) $(TEST_OBJS) $(LIB) $(TEST) *.exe *.map

$(LIB): $(OBJS)
lib -c -n $@ $(OBJS)

%.obj: %.d
$(DMD) $< -of$@ -c $(DMD_FLAGS)

unittest: $(SRCS) $(LIB) $(TEST)

$(TEST): $(OBJS) $(TEST_OBJS)
$(DMD) $(TEST_SRCS) -of$@ $(OBJS) $(DMD_FLAGS)



June 25, 2004
Seems like the system has problems with attachment. If you cannot download the attachment, here is the code in each file + the make file.

====================================
IteratorModule.d
====================================
public interface Iterator(ValueType) {
public bool hasNext();
public ValueType next();
}

====================================
CollectionModule.d
====================================
import IteratorModule;

public interface Collection(ValueType) {

public bool add(ValueType val);
public bool addAll(.Collection!(ValueType) col);
public void clear();
public bool contains(ValueType val);
public bool containsAll(.Collection!(ValueType) col);
public bool isEmpty();
public Iterator!(ValueType) iterator();
public bool remove(ValueType val);
public bool removeAll(.Collection!(ValueType) col);
public bool retainAll(.Collection!(ValueType) col);
public int size();
public ValueType[] toArray();
public void toArray(ValueType[] array);

}

====================================
ListModule.d
====================================
import CollectionModule;

public interface List(ValueType) : Collection!(ValueType) {

public void addAt(int index, ValueType val);
public void addAllAt(int index, Collection!(ValueType) col);
public ValueType get(int index);
public int indexOf(ValueType val);
public int lasIndexOf(ValueType val);
public ValueType removeAt(int index);
public ValueType set(int index, ValueType val);
public .List!(ValueType) subList(int fromIndex, int toIndex);

}

====================================
ArrayListModule.d
====================================
import ListModule;
import IteratorModule;

public class ArrayList(ValueType) : List!(ValueType) {
private int curSize;
private ValueType[] values;
private int incExpcurSize;

public this() {
this(100, 100);
}

public this(int initCapacity) {
this(initCapacity, 100);
}

public this(int initCapacity, int incExpcurSize) {
curSize = 0;
values.length = initCapacity;
incExpcurSize = incExpcurSize;
}

public bool add(ValueType val) {
ensurecurSize(curSize + 1);
values[curSize++] = val;
return true;
}

public void addAt(int index, ValueType val) {
ensurecurSize(curSize + 1);
shiftRight(index, 1);
values[index] = val;
}

public bool addAll(Collection!(ValueType) col) {
Iterator!(ValueType) itor = col.iterator();
while(itor.hasNext()) {
add(itor.next());
}
return true;
}

public void addAllAt(int index, Collection!(ValueType) col) {
ensurecurSize(curSize + col.size);
shiftRight(index, col.size);
Iterator!(ValueType) itor = col.iterator();
for(int i = index; itor.hasNext(); ++i) {
values[i] = itor.next();
}
}

public void clear() {
curSize = 0;
}

public bool contains(ValueType val) {
return indexOf(val) != -1;
}

public bool containsAll(Collection!(ValueType) col) {
Iterator!(ValueType) itor = col.iterator();
while(itor.hasNext()) {
if(!contains(itor.next())) {
return false;
}
}
return true;
}

public bool isEmpty() {
return curSize == 0;
}

public Iterator!(ValueType) iterator() {
return new ArrayListIterator!(ValueType)(curSize, values);
// return new ArrayListIterator!(ValueType)(curSize, curSize);
}

public ValueType get(int index) {
return values[index];
}

public int indexOf(ValueType val) {
for(int i = 0; i < curSize; ++i) {
if(values[i] == val) {
return i;
}
}
return -1;
}

public int lasIndexOf(ValueType val) {
for(int i = curSize - 1; i >= 0; --i) {
if(values[i] == val) {
return i;
}
}
return -1;
}

public ValueType set(int index, ValueType val) {
ValueType oldval = values[index];
values[index] = val;
return oldval;
}

public int size() {
return curSize;
}

public List!(ValueType) subList(int fromIndex, int toIndex) {
int count = toIndex - fromIndex;
ArrayList!(ValueType) subl = new .ArrayList!(ValueType)(count);
subl.values[] = this.values[fromIndex..toIndex];
return subl;
}

public bool remove(ValueType val) {
int pos = indexOf(val);
if(pos != -1) {
shiftLeft(pos, 1);
--curSize;
return true;
}
return false;
}

public ValueType removeAt(int index) {
ValueType oldval = values[index];
shiftLeft(index, 1);
--curSize;
return oldval;
}

public bool removeAll(Collection!(ValueType) col) {
bool changed = false;
Iterator!(ValueType) itor = col.iterator();
while(itor.hasNext()) {
changed = remove(itor.next()) || changed;
}
return changed;
}

public bool retainAll(Collection!(ValueType) col) {
bool changed = false;
for(int index = 0; index < curSize; ) {
if(col.contains(values[index])) {
++index;
} else {
removeAt(index);
changed = true;
}
}
return changed;
}

public ValueType[] toArray() {
ValueType[] result = new ValueType[curSize];
result[] = values;
return result;
}

public void toArray(ValueType[] array) {
array[] = values;

}

private void ensurecurSize(int reqcurSize) {
if(reqcurSize > values.length) {
int newcurSize = reqcurSize - curSize <= incExpcurSize
? incExpcurSize : reqcurSize + incExpcurSize;
values.length = newcurSize;
}
}

private void shiftLeft(int startIndex, int offset) {
for(int index = startIndex; index < curSize; --index) {
values[index - offset] = values[index];
}
}

private void shiftRight(int startIndex, int offset) {
for(int index = curSize - 1; index < startIndex; --index) {
values[index + offset] = values[index];
}
}
}

public class ArrayListIterator(ValueType) : Iterator!(ValueType) {
private int curSize, index;
private ValueType[] data;

public this(int curSize, ValueType[] data) {
// public this(int curSize, int data) {
this.curSize = curSize;
this.data = data;
// this.curSize = data;
index = 0;
}

public bool hasNext() {
return index < curSize;
}

public ValueType next() {
return data[index++];
}
}

====================================
test.d
====================================
import ArrayListModule;

void main()
{
ArrayList!(int) iarray = new ArrayList!(int)();

}

====================================
Makefile
====================================
DMD = dmd
SRCS = \
IteratorModule.d				\
CollectionModule.d				\
ListModule.d						\
ArrayListModule.d
OBJS = $(SRCS:.d=.obj)
TEST_SRCS = test.d
TEST_OBJS = $(TEST_SRCS:.d=.obj)
LIB = stl.lib
TEST = test.exe

all: $(SRCS) $(LIB)

clean:
rm $(OBJS) $(TEST_OBJS) $(LIB) $(TEST) *.exe *.map

$(LIB): $(OBJS)
lib -c -n $@ $(OBJS)

%.obj: %.d
$(DMD) $< -of$@ -c $(DMD_FLAGS)

unittest: $(SRCS) $(LIB) $(TEST)

$(TEST): $(OBJS) $(TEST_OBJS)
$(DMD) $(TEST_SRCS) -of$@ $(OBJS) $(DMD_FLAGS)



June 26, 2004
Sukit Tretriluxana wrote:
> Seems like the system has problems with attachment. If you cannot download the attachment, here is the code in each file + the make file.

I think the problem is with the web interface, not the attachment.

If a person Mozilla Thunderbird, Outlook, or another newsgroup reader, they shouldn't have a problem. (At least, I didn't have a problem using Thunderbird.)

By the way, there's only a delay between posting a message on the web interface and when it shows up on the web. If you could use Thunderbird or Outlook, you'd probably find an easier time of everything. Incidently, the binary .zip file can still be decoded from the web interface by running uudecode (see the attached D source file for instructions if you're interested).


Are you using the Digital Mars make program or another? I got an error
message:
Error on line 21: expecting target : dependencies


Well, I've never felt comfortable with make anyways, so I tried the old
fashioned way:
dmd test.d ArrayListModule.d CollectionModule.d IteratorModule.d
ListModule.d


This is the error I got (DMD 0.93 on WinXP):

ArrayListModule.obj(ArrayListModule)
  Error 42: Symbol Undefined
__Interface_14IteratorModule10Iterator_i8Iterator
--- errorlevel 1

Oh, I just saw that you reposted with a different test file. I'll try to locate the problem from that, but I can't make any promises.


> 
> ====================================
> IteratorModule.d
> ====================================
...

-- 
Justin (a/k/a jcc7)
http://jcc_7.tripod.com/d/


June 27, 2004
Hi Justin and everyone,

Thanks for the reply. Yeb, the error you got is one of the two I am getting. If all the d files are compiled together like what you just did, that's the error I am also getting here. If you instead compile each file individually with -c flag, then link all obj files together at the final step, you will get different but related error as I showed in my first post.

It seems to me that the compiler forgets to generate necessary code. I tried puting a typedef in order to force template instantiation, it kind of fixed the problem. What I mean here is the problem changed. I am still getting link errors but it's for different class. The problem persist even though I keep putting in more typedefs. So I gave up and flags for help her.

Do you or does anyone have any idea what problem I am running into?

Thanks,
Sukit

PS. Thanks for the suggestion to use different client. I will try it.


In article <cbkton$148s$1@digitaldaemon.com>, J C Calvarese says...
>
>This is a multi-part message in MIME format.
>--------------030100000705050201050906
>Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit
>
>Sukit Tretriluxana wrote:
>> Seems like the system has problems with attachment. If you cannot download the attachment, here is the code in each file + the make file.
>
>I think the problem is with the web interface, not the attachment.
>
>If a person Mozilla Thunderbird, Outlook, or another newsgroup reader, they shouldn't have a problem. (At least, I didn't have a problem using Thunderbird.)
>
>By the way, there's only a delay between posting a message on the web interface and when it shows up on the web. If you could use Thunderbird or Outlook, you'd probably find an easier time of everything. Incidently, the binary .zip file can still be decoded from the web interface by running uudecode (see the attached D source file for instructions if you're interested).
>
>
>Are you using the Digital Mars make program or another? I got an error
>message:
>Error on line 21: expecting target : dependencies
>
>
>Well, I've never felt comfortable with make anyways, so I tried the old
>fashioned way:
>dmd test.d ArrayListModule.d CollectionModule.d IteratorModule.d
>ListModule.d
>
>
>This is the error I got (DMD 0.93 on WinXP):
>
>ArrayListModule.obj(ArrayListModule)
>  Error 42: Symbol Undefined
>__Interface_14IteratorModule10Iterator_i8Iterator
>--- errorlevel 1
>
>Oh, I just saw that you reposted with a different test file. I'll try to locate the problem from that, but I can't make any promises.
>
>
>> 
>> ====================================
>> IteratorModule.d
>> ====================================
>...
>
>-- 
>Justin (a/k/a jcc7)
>http://jcc_7.tripod.com/d/
>
>--------------030100000705050201050906
>Content-Type: text/plain;
> name="uudecode.d"
>Content-Transfer-Encoding: 7bit
>Content-Disposition: inline;
> filename="uudecode.d"
>
>/*
> 
>UUDECODE - a Win32 utility to uudecode single files.
>
>Copyright (C) 1998 Clem Dye
>
>This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
>
>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
>
>You should have received a copy of the GNU General Public License
>along with this program; if not, write to the Free Software Foundation, Inc.,
>59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
>
>Modified 13 July 2001 by Clem Dye to allow any character in the range 0 to 7 in the 'begin' statement within the header of the uuencoded file being decoded.
>
>Ported to D: J C Calvarese, 14 May 2004
>
>
>************* Instructions *************
>
>Compile:
>dmd uudecode.d
>
>Usage:
>uudecode.exe d4676.txt
>
>(where d4676.txt would be the input file)
>
>The input file should start with something like this: "begin 0644 stlport.zip" and end with "end".
>
>*/
>
>import std.stream;
>
>
>
>char[] toStringFromChar(char c)
>
>/*
>    based on code posted by Helmut Leitner (helmut.leitner@chello.at),
>    23 Oct 2003 at http://www.digitalmars.com/drn-bin/wwwnews?D/18497
>*/
>
>{
>    char[] s = "?";
>    s[0] = c;
>    return s;
>}
>
>
>
>/* I'll need to do something with this... */
>
>char DEC(char c)
>{
>    return (c - ' ') & 077;
>}
>
>
>
>char[] outname;
>
>char[] uudecode (File f)
>{
>    int n;
>    char ch;
>    char[] buf, p;
>    int pos;
>    File outI = new File();
> 
> 
>    do
>    {
>          buf = f.readLine();
>    }
>    while (buf.length < 4 || buf[0..6] == "begin");
>    pos = 6;
> 
>    while(pos != 0 && find(" 01234567", buf[pos..pos+1]) != -1) pos++;
>    outname = buf[pos..buf.length];
> 
>    /* Create output file and set mode.  */
>    outI.create(outname, FileMode.Out);
> 
>    /* For each input line:  */
>    while(!f.eof)
>    {
>        buf = f.readLine();
>        if (buf.length > 2 && buf[0..5] == "end") break;
>
>        /* n is used to avoid writing out all the characters at the end of the file.  */
>        pos = 0;
>        n = DEC (buf[pos]);
>        if (n <= 0)
>        break;
>        for (++pos; n > 0; /+ p += 4 +/ pos += 4, n -= 3)
>        {
>            p = buf[pos..buf.length];
>            if (n >= 3)
>            {
>                ch = DEC (p[0]) << 2 | DEC (p[1]) >> 4;
>                outI.write(ch); //fputc(ch,outI);
>                ch = DEC (p[1]) << 4 | DEC (p[2]) >> 2;
>                outI.write(ch);  //fputc (ch,outI);
>                ch = DEC (p[2]) << 6 | DEC (p[3]);
>                outI.write(ch);  //fputc (ch,outI);
>            }
>            else
>            {
>                if (n >= 1)
>                {
>                    ch = DEC (p[0]) << 2 | DEC (p[1]) >> 4;
>                    outI.write(ch);
>                }
>                if (n >= 2)
>                {
>                    ch = DEC (p[1]) << 4 | DEC (p[2]) >> 2;
>                    outI.write(ch);
>                }
>            }
>        }
>    }
>    outI.close();
>    return outname;
>}
>
>
>
>int main(char[][] argv)
>{
>    File f;
>
>    int argc = argv.length;
>    debug for(int i; i<argv.length; i++)
>    {
>        printf("Argument %d: %.*s\n", i, argv[i]);
>    }
> 
> 
>    if (argc <= 1) {
>            printf("Usage: %.*s <input file>\n", argv[0]);
>            return 1;
>    }
>    f = new File(argv[1]);
> 
>    /* Check to see if the file is found... */
>    /+if (f.eof /+f == null +/ )
>    {
>            printf("I can't find %.*s\n", argv[1]);
>            return 1;
>    }+/
>    uudecode(f);
>    f.close();
> 
>    printf("Result decoded in %.*s\n", outname);
>    return 0;
>}
>
>--------------030100000705050201050906--