strange long error message

There are 13 of these errors before the compiler stopped,

lexicon.obj : error LNK2019: unresolved external symbol "void __cdecl Error(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?Error@@YAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function "private: void __thiscall Vector<struct Lexicon::charT>::checkRange(int,char const *)" (?checkRange@?$Vector@UcharT@Lexicon@@@@AAEXHPBD@Z)

When I click on the error it does not take me to the location - so I am not sure what code is even the issue.
That's a linker error. The only reason it's long is because you have some template stuff in there (templates generate really bad errors messages usually).

It basically says you defined a function called Error somewhere but you never gave it a definition.
The linker does not see the definition of function

void __cdecl Error(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >);

You use it in your code but either you did not defined it or did not include the file with its definition in the project.
This is where error is defined

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
 * File: genlib.h
 * Last modified on Wed Apr  1 13:17:23 2009 by eroberts
 *      modified on Wed Sep 18 13:41:31 2002 by zelenski
 * -----------------------------------------------------
 * This header file is indicated to be included in
 * all the programs written for CS106B/X and provides a few
 * common definitions. Note this header has a "using namespace std"
 * clause. If a file includes this header, it can then use
 * features from the std namespace without qualifying by scope.
 */

#ifndef _genlib_h
#define _genlib_h

/* This strange-looking pragma is here to disable a warning from Visual C++
 * about truncating long identifiers for debugging symbols. The warning is
 * harmless, but a little disconcernting, so we suppress it. It comes up
 * using STL and other long template expansions.
 */
#if defined(_MSC_VER)
#pragma warning(disable: 4786)
#endif

#include <string>
using namespace std;

/*
 * Function: Error
 * Usage: Error(msg)
 * ------------------
 * Error outputs an error string to the cerr stream and
 * then exits the program with a status code indicating failure.
 */

void Error(string str);

/*
 * Function macro: main
 * --------------------
 * The purpose of this macro definition is to rename the student
 * main to Main in order to allow a custom main defined in our
 * libraries to configure the application before passing control
 * back to the student program.
 */

#ifdef __APPLE__
#define main Main
#endif

#endif 
That's where Error is declared, it just means that void Error(string) is a thing. The definition is what defines what the declaration is/does:

1
2
3
4
void Error(string str)
{
     // Code
}
Last edited on
The error message could be shorter if you did not use standard template class std::string.:)
it is in the library - I am now trying to load the course library to VS. but, maybe it is time for me to away from the course library and use something mainstream.
I think i found it here http://www.ime.usp.br/~pf/Roberts/C-library/standard/cslib/ based on this http://stackoverflow.com/questions/1012119/stanford-engineering-everywhere-cs106b-library

I think the real issue of this thread is i need help transitioning to using class files and assembling these files for my own use; my CS instructors isolated us from this and so i know nothing about it
found it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * File: genlib.c
 * Version: 1.0
 * Last modified on Sun Jul 24 10:29:46 1994 by eroberts
 * -----------------------------------------------------
 * This file implements the general C library package.  See the
 * interface description in genlib.h for details.
 */

#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <stdarg.h>

#include "genlib.h"
#include "gcalloc.h"
#include "exception.h"

/*
 * Constants:
 * ----------
 * ErrorExitStatus -- Status value used in exit call
 * MaxErrorMessage -- Longest error message allowed
 */

#define ErrorExitStatus 1
#define MaxErrorMessage 500

/* Section 1 -- Define new "primitive" types */

/*
 * Constant: UNDEFINED
 * -------------------
 * This entry defines the target of the UNDEFINED constant.
 */

char undefined_object[] = "UNDEFINED";

/* Section 2 -- Memory allocation */

/*
 * Implementation notes:
 * ---------------------
 * The code for the memory allocator is divided between
 * genlib.c and gcalloc.c, and the division strategy may at
 * first seem unnatural, since the function ProtectBlock is
 * declared in gcalloc.h but defined here in genlib.c.  The
 * intention is to minimize the size of object files
 * produced by linkers that search a library for modules
 * that are actually referenced.  The libraries themselves
 * need to call ProtectBlock (usually through the macro
 * ProtectVariable), but will not require the actual code
 * for the allocator unless InitGCAllocator is explicitly
 * called.
 */

/*
 * Global variable: _acb
 * ---------------------
 * This variable is used to hold a method suite that makes it
 * easy to substitute a garbage-collecting allocator for the
 * ANSI allocator.
 */

_GCControlBlock _acb = NULL;

/* Memory allocation implementation */

void *GetBlock(size_t nbytes)
{
    void *result;

    if (_acb == NULL) {
        result = malloc(nbytes);
    } else {
        result = _acb->allocMethod(nbytes);
    }
    if (result == NULL) Error("No memory available");
    return (result);
}

void FreeBlock(void *ptr)
{
    if (_acb == NULL) {
        free(ptr);
    } else {
        _acb->freeMethod(ptr);
    }
}

void ProtectBlock(void *ptr, size_t nbytes)
{
    if (_acb != NULL) _acb->protectMethod(ptr, nbytes);
}

/* Section 3 -- Basic error handling */

/*
 * Implementation notes: Error
 * ---------------------------
 * Writing the Error function requires some care, since it is
 * called in circumstances in which parts of the system may be
 * broken.  In particular, it is not acceptable for Error to
 * call GetBlock, since the error condition may be that the
 * system is out of memory, in which case calling GetBlock would
 * fail.  The error string should be allocated dynamically,
 * so that this function can be used in reentrant code.
 * Note that it is critical to exit if the length bound for
 * an error message is exceeded, since this error almost
 * certainly corrupts the stack.
 */

void Error(string msg, ...)
{
    va_list args;
    char errbuf[MaxErrorMessage + 1];
    string errmsg;
    int errlen;

    va_start(args, msg);
    vsprintf(errbuf, msg, args);
    va_end(args);
    errlen = strlen(errbuf);
    if (errlen > MaxErrorMessage) {
        fprintf(stderr, "Error: Error Message too long\n");
        exit(ErrorExitStatus);
    }
    if (_acb == NULL) {
        errmsg = malloc(errlen + 1);
    } else {
        errmsg = _acb->allocMethod(errlen + 1);
    }
    if (errmsg == NULL) {
        errmsg = "No memory available";
    } else {
        strcpy(errmsg, errbuf);
    }
    if (HandlerExists(&ErrorException)) {
        RaiseException(&ErrorException, "ErrorException", errmsg);
    } else {
        fprintf(stderr, "Error: %s\n", errmsg);
        exit(ErrorExitStatus);
    }
}

I've never used elipsis arguments so someone please correct me if I'm wrong but it looks to me that the declaration of Error() is incorrect as it's missing the elipsis argument (the declaration is 6 posts up for those that may have missed it).

Edit: Assuming of course this is the intended definition for the declaration.
Last edited on
This declaration

void Error(string str);


does not correspond to this declaration

void Error(string msg, ...);

So maybe this inconsistence in declarations became the reason of the linker error.

The linker did not find the definition of void Error(string str); because there is only the definition of void Error(string msg, ...); in the project.
Last edited on
after some research I found that the linker errors are the result of some kind of change in VS2010 from pre-2008 versions, http://melbsdailydigest.blogspot.com/2010/09/cs106b-libraries-and-following-along.html

any idea what haas changed and what I can do to correct this?
Beginning saying "I know nothing about VS106B or whatever".
Your declaration:
void Error(string str);
should be changed, as previously said, into
void Error(string str, ...);
fixed it; I found two differing year versions of .c and .h, 1994 and 2002; will be conscious of this next time
Topic archived. No new replies allowed.