So I have this function for hashing internal strings, but when I try to run it Visual Studio 2015 gives me a Debug Assertion Failed! Error:
Program: C:\WINDOWS\SYSTEM32\MSVCP140D.dll
File: c:\program files (x86)\microsoft visual studio 14.0\vc\include\vector
Line: 1232
Expression: vector subscript out of range
Now the first time InternalString gets called I get this error and it breaks on the gStringIdTable.find(sid) line.
static std::unordered_map<StringId, const char*> gStringIdTable;
StringId InternalString(const char* string) {
StringId sid = std::hash<std::string>()(string);
std::unordered_map<StringId, const char*>::iterator it = gStringIdTable.find(sid);
if (it == gStringIdTable.end()) {
gStringIdTable.insert({sid, string});
}
return sid;
}
I thought maybe it was a problem with the way I was initializing the iterator so I figured I'd try this:
if (gStringIdTable.find(sid) == gStringIdTable.end()) {
gStringIdTable.insert({sid, string});
}
But that gives me the same error. Then I thought maybe it had to do with doing the find before the unordered_map was populated with anything so I tried ONLY doing an insert in the function. But that too gave me the same error. I tried converting the const char* to std::string, and then only dealing with strings in the unordered_map at this answer's suggestion, but got the same error. I tried using emplace instead of insert, tried using std::make_pair, but all combinations to no avail.
Now, am I missing something obviously wrong, or is there bug somewhere?
Update
Okay so here is a compiling version where I still get the error. I started an empty c++ project in visual studio 2015 and added these 3 files to match how it is currently implemented in my project:
main.cc
#include "stringid.h"
const static mynamespace::StringId kSidOne = mynamespace::InternalString("One");
int main(int argc, char *argv[]) {
return 0;
}
stringid.cc
#include "stringid.h"
#include <string>
#include <unordered_map>
namespace mynamespace {
static std::unordered_map<StringId, std::string*> gStringIdTable;
StringId InternalString(const char* string) {
StringId sid = std::hash<std::string>()(string);
if (gStringIdTable.find(sid) == gStringIdTable.end()) {
gStringIdTable.emplace(sid, new std::string(string));
}
return sid;
}
} // mynamespace
string.h
#ifndef STRINGID_H_
#define STRINGID_H_
namespace mynamespace {
typedef unsigned int StringId;
StringId InternalString(const char* string);
} // mynamespace
#endif // STRINGID_H_
I also did some debugging into the functions to see if I could figure out where the problem is arising from and it looked like when the find function grabs the relevant bucket it returns null or 0 and then the _Begin function throws and error because the size is equal to zero.
Small Update
I also tried compiling with gcc. It compiles fine, but I still get an error on find().
You're keying the hash table with... a hash.
That's an error. The hash is not unique.
What you want to do is to key the hash table with... a key!
How the table hashes is an implementation detail and you shouldn't see on the outside.
Simplest way to fix this would be to e.g. use std::unordered_set<std::string>.
Live On Coliru
#include <unordered_set>
const char* InternalString(const char* string) {
static std::unordered_set<std::string> s_table;
std::unordered_set<std::string>::iterator it = s_table.find(string);
return (it != s_table.end())? it->c_str() : s_table.insert(string).first->c_str();
}
#include <cassert>
int main() {
auto a = InternalString("HelloWorld" + 5);
auto b = InternalString("World");
assert(a == b);
}
The assert verifies ok, since World and World match, even though the raw pointer was different.
You can make this a lot more efficietn (by e.g. using some set with a custom key comparator)
The simplest way of defining my problem is that I'm trying to implement a mechanism that would check whether the same string had already been used (or a pair (number, string)). I would like this mechanism to be implemented in a smart way using C preprocessor. I would also like that this mechanism gave me compile errors when there is a conflict or run-time errors in Debug mode (by checking assertions). We don't want the developer to make a mistake when adding a message, as every message should be unique. I know that it could be done by calculating a hash or for example crc/md5 but this mechanism would be conflict-vulnerable which I need to avoid. It is crucial that every message can be used only once.
Example behaviour of this mechanism:
addMessage(1, "Message1") //OK
addMessage(2, "Message2") //OK
.
.
.
addMessage(N, "MessageN") //OK
addMessage(2, "Message2") //Compile error, Message2 has already been used
Alternative behaviour (when Debugging code):
addMessage(1, "Message1") //OK
addMessage(2, "Message2") //OK
.
.
.
addMessage(N, "MessageN") //OK
addMessage(2, "Message2") //Assertion failed, because Message2 has already been used
The preferred way of doing it would be smart usage of #define and #undef directives. In general the preprocessor should be used in a smart way (I am not sure if this is possible) maybe it can be achieved by appropriate combinations of macros? Any C preprocessor hacker that could help me solve this problem?
//EDIT: I need those messages to be unique globally, not only inside one code block (like function of if-statement).
//EDIT2: The best description of the problem would be that I have 100 different source files and I would like to check with a preprocessor (or possibly other mechanism other than parsing source files with a script at a start of the compilation every-time, which would be very time-consuming and would add another stage to an enough complicated project) if a string (or a preprocessor definition) was used more than one time. I still have no idea how to do it (I know it may not be possible at all but I hope it actually is).
This will give an error on duplicate strings:
constexpr bool isequal(char const *one, char const *two) {
return (*one && *two) ? (*one == *two && isequal(one + 1, two + 1))
: (!*one && !*two);
}
constexpr bool isunique(const char *test, const char* const* list)
{
return *list == 0 || !isequal(test, *list) && isunique(test, list + 1);
}
constexpr int no_duplicates(const char* const* list, int idx)
{
return *list == 0 ? -1 : (isunique(*list, list + 1) ? no_duplicates(list + 1, idx + 1) : idx);
}
template <int V1, int V2> struct assert_equality
{
static const char not_equal_warning = V1 + V2 + 1000;
};
template <int V> struct assert_equality<V, V>
{
static const bool not_equal_warning = 0;
};
constexpr const char* l[] = {"aa", "bb", "aa", 0};
static_assert(assert_equality<no_duplicates(l, 0), -1>::not_equal_warning == 0, "duplicates found");
Output from g++:
g++ -std=c++11 unique.cpp
unique.cpp: In instantiation of ‘const char assert_equality<0, -1>::not_equal_warning’:
unique.cpp:29:57: required from here
unique.cpp:20:53: warning: overflow in implicit constant conversion [-Woverflow]
unique.cpp:29:1: error: static assertion failed: duplicates found
The first template parameter (in this case 0) to 'assert_equality' tells you the fist position of a duplicate string.
I am not sure that it is easily doable using the standard C++ preprocessor (I guess that it is not). You might use some other preprocessor (e.g. GPP)
You could make it the other way: generate some X-macro "header" file from some other source (using e.g. a tiny awk script, which would verify the unicity). Then customize your build (e.g. add some rules to your Makefile) to run that generating script to produce the header file.
Alternatively, if you insist that processing being done inside the compiler, and if your compiler is a recent GCC, consider customizing GCC with MELT (e.g. by adding appropriate builtins or pragmas doing the job).
In the previous century, I hacked a small Emacs function to do a similar job (uniquely numbering error messages) within the emacs editor (renumbering some #define-s before saving the C file).
I am going to assume that something like this will work:
addMessage(1, "Message1")
addMessage(2, "Message1")
Or:
addMessage(1, "Message") /* transforms into "Message_1" */
addMessage(2, "Message_1") /* transforms into "Message_1_2" */
Because the C preprocessor expands tokens lazily and prohibits defining a macro from within another macro, it is impossible to save the results of executing one macro so that another macro can make use of it.
On the other hand, it is definitely possible to force uniqueness of symbols:
#define addMessage(N, MSG) const char *_error_message_##N (void) { return MSG; }
Or:
#define addMessage(N, MSG) const char *_error_message_##N (void) { return MSG "_" #N; }
Because during the link step, duplicate symbols with the name _error_message_NUMBER will trigger an error. And because it is a function, it cannot be used inside of another function without triggering an error.
Assuming your compiler is still not C++11 compliant as you have not tagged appropiately. I am also assuming that you are not particular about the Error Message, its just that you want it to work. In which case, the following Macro Based Solution might work for you
#include <iostream>
#include <string>
#define ADD_MESSAGE(N, MSG) \
char * MSG; \
addMessage(N, #MSG);
void addMessage(int n, std::string msg)
{
std::cout << msg << std::endl;
}
int main() {
ADD_MESSAGE(1, Message1); //OK
ADD_MESSAGE(2, Message2); //OK
ADD_MESSAGE(3, MessageN); //OK
ADD_MESSAGE(4, Message2); //Compile error, Message2 has already been used
};
Compile Output
prog.cpp: In function ‘int main()’:
prog.cpp:17:17: error: redeclaration of ‘char* Message2’
ADD_MESSAGE(4, Message2); //Compile error, Message2 has already been used
^
prog.cpp:4:8: note: in definition of macro ‘ADD_MESSAGE’
char * MSG; \
^
prog.cpp:15:17: error: ‘char* Message2’ previously declared here
ADD_MESSAGE(2, Message2); //OK
^
prog.cpp:4:8: note: in definition of macro ‘ADD_MESSAGE’
char * MSG; \
^
If you don't care about large amounts of useless boiler plate then here's one that's entirely the preprocessor, so no worries about scope, and then checks that they are unique at program startup.
In a file:
#ifndef ERROR1
#define ERROR1 "1"
#endif
#ifndef ERROR2
#define ERROR2 "2"
#endif
...
#ifndef ERROR255
#define ERROR255 "255"
#endif
#include <assert.h>
#include <set>
#include <string>
class CheckUnique {
CheckUnique() {
std::set<std::string> s;
static const char *messages = {
#if HAVE_BOOST
# include <boost/preprocessor.hpp>
# define BOOST_PP_LOCAL_LIMITS (1, 254)
# define BOOST_PP_LOCAL_MACRO(N) ERROR ## N,
# include BOOST_PP_LOCAL_ITERATE()
#else // HAVE_BOOST
ERROR1,
ERROR2,
...
#endif // HAVE_BOOST
ERROR255
};
for (int i = 0; i < sizeof messages / sizeof *messages; i++) {
if (s.count(messages[i]))
assert(! "I found two error messages that were the same");
else
s.insert(messages[i]);
}
}
};
static CheckUnique check;
This file can then be #included at the end of each source file, or you can place it into a file of its own and include every single file that has a #define ERROR line in it. That way, as soon as the operating system loads the program, the constructor for check will run and throw the exception.
This also requires you to have access to the Boost.Preprocessor library (and it's header only so it's pretty easy to set up). Although if you can't use that, then you can just hard code the error macros as I have shown with the #if HAVE_BOOST block.
Most of the boiler plate here is pretty simple, so if you generated it with a program (like some sort of portable script) then it would make your life far easier, but it can still be done all in one shot.
I'm normally good at googling stuff like this but I can't seem to find anything this time.
I downloaded some source code from here and it uses a function called roundf.
I already have #include <math.h> and as a first thought added #include <cmath> but still have the problem. I can't seem to find out where the function originates...
Is there an alternative function? Or does anyone know where it comes from so I can include the header file?
The roundf() function is defined by C99, but MSVC implements very little of C99, so it is not available with the Microsoft compilers.
You can use this one:
float roundf(float x)
{
return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f);
}
You also can use a boost library:
#include <boost/math/special_functions/round.hpp>
const double a = boost::math::round(3.45); // = 3.0
const int b = boost::math::iround(3.45); // = 3
I have a file named mama. This file contains 3 files named child1 child2 and child3. child1 contains 5 txts,child2 contains 7 txts and child3 contains 4 txts. The path of mama is C:\Users\John\Desktop\mama .Sorry for my way of writing but i am trying to explain exactly my case. My goal is to find the paths of all these txts(16 in number) so i can do things with them. So i think a function that finds this paths and put them in a linked list
struct paths
{
string pathName;
paths *next;
};
would be exactly what i need to use them one by one. I found some examples about FindFirstFile() and FindNextFile(), i also tried to run some code so i could understand with some testing how it works but erros keep apeared forbiding the oportunity for testing and understanding. By the way i use visual Studio 2008(it's the one they said we should use so i guess i can't change it). If someone can help me understand or got any link that would have some good and somehow easy to understand examples i would be really thankfull.
Edit:
For example with this code
#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
WIN32_FIND_DATA fData;
void * handle = FindFirstFile( "C:/Users/John/Desktop/*", &fData );//<~~~error
cout << fData.cFileName;
system("pause");
}
There is 1 error: Error 1 error C2664: 'FindFirstFileW' : cannot convert parameter 1 from 'const char [24]' to 'LPCWSTR'
first, you should declare a WIN32_FIND_DATA structure
then find the first file in a directory ( ie C:/Users/John/Desktop/* )
paths * head;
WIN32_FIND_DATA fData;
void * handle = FindFirstFile( "C:/Users/John/Desktop/*", &fData );
check to see if it's the file you want using:
fData.cFileName // the file name is stored here ( ie C:/Users/John/Desktop/child2.txt )
you can do this in a loop:
while( !CheckFileNameHere( fData.cFileName, head->pathname ) ) FindNextFile( handle, &fData );
increment the list:
head = head->next;
or finish:
CloseHandle( handle );
How you obtain the paths is up to you. If you have stored them in a file, use and of the
functions from stdio.h, iostream, or windows.h. If you write this as a function, you can reuse it for any file name you have.
If you are getting runtime errors using these methods, you should post the exact errors so that we can figure out why they aren't working. Same goes for compilation errors.
My problem is that when I want to make a downloaded library I get some weird compile errors from GCC and the code that the compiler demands to correct seems just to be right.
The errors are all like this:
Catalogue.h:96: error: there are no
arguments to ‘strlen’ that depend on a
template parameter, so a declaration
of ‘strlen’ must be available
Here is the code around line 96:
GaCatalogueEntry(const char* name, T* data)
{
if( name )
{
_nameLength = (int)strlen( name ); // LINE 96
// copy name
_name = new char[ _nameLength + 1 ];
strcpy( _name, name ); // LINE 100: similar error
_data = data;
return;
}
_name = NULL;
_nameLength = 0;
_data = NULL;
}
What can I do to fix these compile errors?
You probably just need to include the header that contains the strcpy and strlen library functions.
#include <string.h>
or (preferably for C++)
#include <cstring>
In C++ the strlen() function is part of the string library, and it almost looks like the header file was not included.
Is it included anywhere?
include <string.h>
If not, try adding it and see if that fixes the problem.
The code is buggy. You are probably missing an #include <string.h>.
If you don't want to change the code, add -fpermissive to the compiler options. (See the GCC documentation.)
a declaration of ‘strlen’ must be available
Include string.h or <cstring> (C++) for the declaration of strlen().