The explicit keyword in MS Visual Studio 4.1 - visual-c++

I am implementing a smart pointer class using generics and I wanted to force users of this class to properly construct the smart pointer using syntax such as
MyReference<TestCls>(mytest3))
or
MyReference<TestCls> mytest4(new TestCls());
so I have used the explicit keyword on the CTOR, to prevent this:
MyReference aRef = NULL;
However due to unfortunate circumstances beyond my control, I am working on code that is compiled using the ancient MSVC++ 4.1 compiler. I get the following errors when I include the explicit keyword:
MyReference.h(49) : error C2501: 'explicit' : missing decl-specifiers
MyReference.h(51) : error C2143: syntax error : missing ';' before ''
MyReference.h(52) : error C2238: unexpected token(s) preceding ':'
MyReference.h(52) : error C2059: syntax error : 'int constant'
When I add a #define explicit those errors disappear.
This was a hack on my part, just to get the compiler to ignore the keyword. I'm guessing that this means that explicit is not supported by yon olde compiler.
Can someone confirm this and is there anyone out there with knowledge of a workaround solution for this?
Merci Beaucoups,
Dennis.

This site has a workaround for this, namely:
Unfortunately, older compilers may not
support the use of "explicit", which
could be a headache. If you're stuck
working with an out-of-date compiler
and can't get one that has better
support for the C++ standard, your
best solution may be to take advantage
of the fact that only a single
implicit conversion will take place
for a given value. You can exploit
this by using an intermediate class
that implicitly creates an object of
each type, and then have your main
class implicitly create objects from
that class:
class proxy
{
public:
proxy(int x) : x(x) {} ;
getValue() { return x; }
private:
int x;
};
class String
{
// this will be equivalent of explicit
String(proxy x) { /* create a string using x.getValue(); */ }
}

Related

Inline C Varnish (VCL_deliver)

I am using Varnish 4.0.
My backend is adding to some responses an http header "x-count"
I would like to log the value of "x-count" into a file with a line break.
I assumed i should do it in VCL deliver.
Here is what i have so far :
sub vcl_deliver {
if (resp.http.x-count-this:) {
set resp.http.X-infodbg = "xx";
C{
FILE *fp;
fp = fopen("/tmp/test.txt", "w+");
fputs(VRT_GetHdr(sp, HDR_OBJ, "\013x-count-this:"), fp);
fputs("\n", fp);
fclose(fp);
}C
}
}
Of course it doesnt work and there is a couple of errors ..
./vcl.gK2lu7uM.c: In function ‘VGC_function_vcl_deliver’:
./vcl.gK2lu7uM.c:1049:22: error: ‘sp’ undeclared (first use in this
function) ./vcl.gK2lu7uM.c:1049:22: note: each undeclared identifier
is reported only once for each function it appears in
./vcl.gK2lu7uM.c:1049:5: error: passing argument 2 of ‘VRT_GetHdr’
makes pointer from integer without a cast [-Werror]
./vcl.gK2lu7uM.c:330:7: note: expected ‘const struct gethdr_s *’ but
argument is of type ‘int’ ./vcl.gK2lu7uM.c:1049:5: error: too many
arguments to function ‘VRT_GetHdr’ ./vcl.gK2lu7uM.c:330:7: note:
declared here
I have to say that i simply copy/pasted "sp" from some examples, but i have no idea where it comes from (i suppose the inline C was in a different context and therefore it was declared there but not in vcl_deliver)
So the probably undocumented differences between Varnish 4 and 3 in the above examples are :
VRT_GetHdr is now VRT_GetHdr(context, struct gethdr_s)
sp doesn't exist, but there is a "ctx" variable
Found this, there :
http://jan.bogutzki.de/Artikel/395/set-ttl-in-varnish-4.html
char *stuffid;
const struct gethdr_s hdr = { HDR_BERESP, "\015x-count-this:" };
stuffid = VRT_GetHdr(ctx, &hdr);
And now a different story: Varnish is crashing as soon as the backend sends back "count-this", but that is a different problem :p (my crappy C code probably)
I don't have Varnish 4.0 handy to test this out, but I was able to get your example working with Varnish 3.0. When I tried the VCL as is, I wasn't getting the exact error you are though. The first change:
if (resp.http.x-count-this:) {
needs to be:
if (resp.http.x-count-this) {
The colon should be left off of the header name when referred to this way. Next:
fputs(VRT_GetHdr(sp, HDR_OBJ, "\013x-count-this:"), fp);
needs to be:
fputs(VRT_GetHdr(sp, HDR_OBJ, "\015x-count-this:"), fp);
The length value in that string needs to be in octal for some reason, and 13 in octal is 15. Making those changes got this to work for me. That being said, you many want to look into using open and fcntl instead of fopen since without file locking I'm not sure what the effect of multiple requests contending for that file would be.

redefinition of default parameter error without redefining

I am getting a strange set of error in my Visual Studio 2010 compiler.
I am getting the errors of
error C2572: redefinition of default parameter
error C2011: 'class' type redefinition
I have checked thoroughly and I know very well that in the function definition, I have not given the default parameter values and I have given default parameter value only in function prototype in the header file.
Also, I am very much sure that no two class has been given the same class name.
Please can anybody tell me what could be the other reasons for getting these set of errors?
I have not got the exact reason why it was happening, but I have overcome it by using some simple techniques.
I used function overloading concept to avoid default parameter list. It will cause in duplication of code, but it has proved to be very effective.
So something like this
void myFunction( int, char * = '\0', char * = '\0' );
would become something like this
void myFunction( int );
void myFunction( int, char * );
void myFunction( int, char *, char * );
In this example, code is getting duplicated two times but it seems to be only work around solution.
Next, for the strange class type redefinition error, I was instantiating the class variable in many files. So, I removed that feature of instantiation everywhere and went with global variable something like this.
File named as myHeader.h
#include "myFile.h"
myClass myObj;
And in all the other files
#include "myHeader.h"
myObj.function1( );
myObj.function2( );

c2664 in Visual Studio 2012 when using make_pair

I dig up an old project and wanted to compile it, but received several errors, a few of those being a c2664:
error C2664: 'std::make_pair' : cannot convert parameter 1 from 'CUser *' to 'CUser *&&'
error C2664: 'std::make_pair' : cannot convert parameter 1 from 'unsigned long' to ' unsigned long &&'
The relevant code parts are:
//typedef for the userdata map
typedef std::map<unsigned long, std::pair<CUser*,userstatus*>> UserDataMapType;
//...
Inc::incret CUserManager::AddUser(unsigned long ID, CUser* pUser, userstatus* pUserStatus)
{
//...
std::pair<UserDataMapType::iterator, bool> ret = m_mapUserData.insert(std::make_pair<unsigned long, std::pair<CUser*, userstatus*>>(ID, std::make_pair<CUser*, userstatus*>(pUser, pUserStatus)));
//...
}
I tried to make the function parameters const, but that did not help.
It did compile just fine in VS2010.
Please help me find what causes this and how to solve it.
make_pair() has been changed in VS2012 to support a new C++11 feature called move semantics and I suspect that explicitly specifying the types for make_pair() is getting in the way.
Remember that make_pair() does not need any template parameters to be explicitly specified. It deduces them from the type of each argument.
Try removing the explicit template arguments from both calls to make_pair() like so...
std::pair<UserDataMapType::iterator, bool> ret = m_mapUserData.insert(std::make_pair(ID, std::make_pair(pUser, pUserStatus)));
Explicitly providing them like this would have worked fine pre-VS2012 because of a new C++11 feature added called move semantics. You'll want to read up on that subject later since you have a shiny new compiler that supports it.

how visual studio tell c++ and c?

As the title says,does the visual studio distinguish these two files by their suffix?.c or .cpp?
I also have another question.At first,I stated the program like this:
int main(int argc, char **argv)
{
LARGE_INTEGER TimeStart;
LARGE_INTEGER TimeEnd;
QueryPerformanceCounter(&TimeStart);
static double Freq;
static int getfreq;
double mu,om;
double *v;
int it,i,j;
....
}
but it brings out many problems:
1>sor2d.c(23): error C2143: syntax error : missing ';' before 'type'
1>sor2d.c(24): error C2143: syntax error : missing ';' before 'type'
1>sor2d.c(25): error C2143: syntax error : missing ';' before 'type'
1>sor2d.c(26): error C2143: syntax error : missing ';' before 'type'
23 ling points to "static double Freq;"
but if I put "QueryPerformanceCounter(&TimeStart);" after the data allocation,the compiler can succeed.Could someone tell me why this happened,was is just because of my carelessness of omitting something or ignorance...?
In C, all variables must be declared before calling any methods.
Visual Studio will, by default, compile .C files as C. You can override this.
In C89, you must declare all of your variables at the top of the code block. You may also initialize them to compile-time constants (literals, macros that expand to literals, the values of variables that have already been initialized, and any operations on the above that can be performed at compile time). You cannot intersperse other types of statements (like function calls) within these declarations.
This limitation was removed in C99 (which is not supported by Visual C++) and C++.

What is the use of CComPtr over CComQIPtr in COM?

Can any one explain, What is the use of CComPtr over CComQIPtr in COM?
CComPtr<ISampleInterface> Sample1;
CComQIPtr<ISampleInterface> Sample2;
CComQIPtr is for cases when you want to call QueryInterface() in a convenient manner to know whether an interface is supported:
IInterface1* from = ...
CComQIPtr<IInterface2> to( from );
if( to != 0 ) {
//supported - use
}
This way you can request an interface from a pointer to any (unrelated) COM interface and check whether that request succeeded.
CComPtr is used for managing objects that surely support some interface. You use it as a usual smart pointer with reference counting. It is like CComQIPtr, but doesn't allow the usecase described above and this gives you better type safety.
This code:
IUnknown* unknown = ... ;
CComQIPtr<IDispatch> dispatch( unknown );
compiles and maybe yields a null pointer if unknown is bound to an object that doesn't implement IDispatch. You now have to check for that in runtime which is good if you wanted a runtime check in the first place but bad if you'd prefer a compile time type check.
This code:
IUnknown* unknown = ... ;
CComPtr<IDispatch> dispatch( unknown );
will simply not compile - it yields
error C2664: 'ATL::CComPtr::CComPtr(IDispatch *) throw()' : cannot convert parameter 1 from 'IUnknown *' to 'IDispatch *'
which provides for better compile time type safety.
template<class T,
const IID* piid = &__uuidof(T)>
class CComQIPtr: public CComPtr<T>
Former deduces the UUID of given type automatically, via default template argument.
The following MSDN article explains the difference and recommends using CComPtr instead of CComQIPtr
How to: Create and Use CComPtr and CComQIPtr Instances
Remark on the answer of sharptooth. Just tried to compile sth. like
CComQIPtr<IInterface2> to( from );
and failed. Assignment instead worked:
CComQIPtr<IInterface2> to = from;
Unfortunately I have no time to analyse this further...
"ATL uses CComQIPtr and CComPtr to manage COM interface pointers. Both classes perform automatic reference counting through calls to AddRef and Release. Overloaded operators handle pointer operations. CComQIPtr additionally supports automatic querying of interfaces though QueryInterface."
And where do you use one over the other?
When you do not want to call 'QueryInterface()' 'manually', use 'CComQIPtr':
CComQIPtr( T* lp );
CComQIPtr( const CComQIPtr< T, piid >& lp );
If you pass a pointer type derived from T, the constructor sets p to the T* parameter and calls AddRef. If you pass a pointer type not derived from T, the constructor calls QueryInterface to set p to an interface pointer corresponding to piid.

Resources