I have a Function which checks to see if IIS is installed and gets the installation path.
int IsIISInstalled(string &pathname)
{
DWORD returnvalue;
long keyres = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\InetStp\\", 0, KEY_READ, &miva);
if (keyres == ERROR_SUCCESS)
{
char szBuffer[512];
DWORD dwBufferSize = sizeof(szBuffer);
ULONG nError;
nError = RegQueryValueExA(miva, "InstallPath", NULL, NULL, (LPBYTE)szBuffer, &dwBufferSize);
if (nError == ERROR_SUCCESS)
{
char retBuffer[512];
DWORD nsize = sizeof(retBuffer);
returnvalue = ExpandEnvironmentStringsA(szBuffer, retBuffer, nsize);
pathname = retBuffer;
}
}
if (!pathname.empty())
return 1;
else
return 0;
}
When i attach to my executable and debug this there is a return value from ExpandEnvironmentStringsA
in retBuffer showing the installation path. returnvalue shows 28 as is the TCHARS that was put in the buffer. Once i step into the next line setting the string pathname to the retBuffer it fails giving me a string subscript out of range. I understand what that error means, i have done it plenty of times. What is odd to me is if i specify a new string var in the function:
string fakeresult;
and set fakeresult to retBuffer:
fakeresult = retBuffer;
just as i am in the code above it passes through just fine with no errors. I am calling the function with this code.
string iis_path, miva_path;
int disable;
char *full_path;
//getMivaLocation(miva_path);
bool good2go;
int iisinstalled, empressaReturn, miaReturn;
iisinstalled = IsIISInstalled(iis_path);
Does this have to do with the fact i am passing pathname by reference to the function?
If that is the case why?
How could i fix this to be able to return my data?
I am not a well educated c++ coder i am learning a lot of this as i go and have learned much from you guys. Hoping someone has an idea on this as i do not wish to spend much more time researching to no avail. Thanks.
After stepping into further i found that the pathname is being set as it should. It is immediately crashing on the next call to another functions so my debugging was incorrect. Now i have scoped further hopefully i can fix this. Also for my own note, the reason why it would not crash when i set fakestring instead of pathname was due to the fact i was passing pathname in the function call that is crashing. With no value it is not setting something out of its scope.
Related
I have a SourceLocation that I wish to extract its filename from. Apparently, I should be able to do that by using SourceManager's getFilename. However, the result seems to always be an empty string when I process some header files.
I follow the source code and found that the issue is that in the getFilename function, which reads:
/// Return the filename of the file containing a SourceLocation.
StringRef getFilename(SourceLocation SpellingLoc) const {
if (const FileEntry *F = getFileEntryForID(getFileID(SpellingLoc)))
return F->getName();
return StringRef();
}
The result of getFileID is somehow invalid in a sense that SLocEntry constructed from it will have isFile returning false. This causes getFileEntryForID (which does construct SLocEntry under the hood) to return a null pointer.
I have a workaround, which is:
StringRef myGetFilename(SourceLocation SpellingLoc) const {
std::pair<FileID, unsigned> locInfo = getDecomposedExpansionLoc(SpellingLoc);
if (const FileEntry *F = srcManager.getFileEntryForID(locInfo.first))
return F->getName();
return StringRef();
}
That is, call getDecomposedExpansionLoc first to get a raw FileID and use it in getFileEntryForID instead.
Experimentally, this seems to work well, but this is my first day with clang, so I'm very unsure if it's actually correct. So I have two questions:
Is this a bug in clang?
Is my workaround actually correct?
Thanks!
Ah, so the problem seems to be that getFilename expects a specific kind of SourceLocation, namely "SpellingLoc". So, change:
srcManager.getFilename(loc)
to
srcManager.getFilename(srcManager.getSpellingLoc(loc))
will fix the problem.
This is my first Xcode app and objective-c so give me some slack :)
I tried googling on the issue but I cannot see any help regarding Xcode and app development. I added the error masseages after //
- (id)initWithBytes:(int8_t)byte1, ... { //Error: 1. Parameter of type 'int8_t' (aka 'signed char') is declared here
va_list args;
va_start(args, byte1); //Error: Passing an object that undergoes default argument promotion to 'va_start' has undefined behavior
unsigned int length = 0;
for (int8_t byte = byte1; byte != -1; byte = va_arg(args, int)) {
length++;
}
va_end(args);
if ((self = [self initWithLength:length]) && (length > 0)) {
va_list args;
va_start(args, byte1); // Error: Passing an object that undergoes default argument promotion to 'va_start' has undefined behavior
int i = 0;
for (int8_t byte = byte1; byte != -1; byte = va_arg(args, int)) {
_array[i++] = byte;
}
va_end(args);
}
return self;
}
Thank you in advance!!
va_start() saves the pointer to the first argument passed to the function into a va_list.
The arguments themselves are passed via a hardware stack.
The issue with int8_t comes from the way the hardware stack is implemented. (in x86 at least)
Just like the SSE and MMX does, the stack requires elements stored on it to have an alignment equal to a multiple of 16bits, so everything passed to the function WILL have at least 16 bits of size, regardless of its type.
But the problem is va_arg() doesn't know about all that. Historically, it was a macro, and all it does is returning a pointer stored in va_list, and incrementing va_list by sizeof(type).
So, when you retrieve the next argument, the pointer returned does not point to the next argument but one byte before it, or not - depending on whether the va_arg is a macro or a compiler built-in function.
And this is what a warning is about.
IMO at least. Pardon my English, It's my 2nd language.
For one of my requirements I need the JSON GENERATE function in COBOL 6. My problem is, that it returns UTF-8, but I need the data in EBCDIC (CCSID 1140). Is there a way to convert this? Every solution I found uses national data types, but I have to use the NODBCS compiler option, so those don't work.
I do apologize for not first asking a question (but I am too new to StackOverflow to allow that.) The question would be "do you have C++ and can you link C++ with your COBOL?" I just tried this program:
#include <iconv.h>
class myConv
{
public:
static myConv globalConv;
size_t conv(char ** restrict f, unsigned int * restrict flen,
char ** restrict t, unsigned int * restrict tlen)
{
if (ok_)
{
return iconv(cd_, f, flen, t, tlen);
}
else
{
return (size_t)-1;
}
}
private:
myConv()
{
cd_ = iconv_open("1047", // EBCDID
"1208"); // UTF-8
ok_ = (cd_ != (iconv_t)-1);
// possibly indicate what the error is
}
~myConv()
{
if (ok_)
{
if (iconv_close(cd_) != 0)
{
// possibly indicate what the error is
}
}
}
bool ok_;
iconv_t cd_;
};
myConv myConv::globalConv;
extern "C" bool CNV(char * f, unsigned int flen,
char * t, unsigned int tlen)
{
return myConv::globalConv.conv(&f, &flen,
&t, &tlen) != (size_t)-1;
}
and the COBOL call looked like this:
json generate result from grp
call "CNV" using by reference result,
by value length of result,
by reference convertedres,
by value length of convertedres,
returning cres
and cres is a PIC S9(9) COMP data item which will have a non-zero value of the conversion succeeded.
Again, I apologize for not first asking if C++ is a possibility. (Or even C. The code could be easily done in C.) Also, the result is not quite perfect owing to the JSON GENERATE result being zero filled.
Pretty sure the answer is No on this one, but it's painful enough I have to ask: Is there a CFNumber equivalent to CFString's CFSTR macro? To avoid this sort of thing:
char one = 1;
CFNumberRef cfONE = CFNumberCreate(kCFAllocatorDefault, kCFNumberCharType, &one);
if (cfONE != NULL) {
... finally I can compare something to the number 1! ...
CFRelease(cfONE);
} else {
// not likely, but possible, if you really want to be conservative
}
Note that I'm not using Objective-C in this particular code.
Eric
If you plan on using this function multiple times, you could the static modifier and stop worrying about deallocation:
static CFNumberRef cfONE = NULL;
if (cfONE == NULL) {
static char one = 1;
cfONE = CFNumberCreate(kCFAllocatorDefault, kCFNumberCharType, &one);
assert (cfONE != NULL); // Oh no, destroy the world!
}
// ... finally I can compare something to the number 1! ...
So long as you have static, the static analyzer will leave you alone on the leak issue since it is an expected constant size memory allocation, O(1) rather than O(n) where n is the number of executions.
There are several ways to make this a macro. I came up with this lazy one:
#define CFNUMDEF(name, type, numberType, value) \
static CFNumberRef name = NULL; \
if ( name == NULL) { \
static type val = value ;\
name = CFNumberCreate(kCFAllocatorDefault, numberType , &val);\
assert ( name != NULL); \
}
CFNUMDEF(cfONE, char, kCFNumberCharType, 1);
// ... finally I can compare something to the number 1! ...
CFSTR is a little different from your case
CFSTR() allows creation of compile-time constant CFStringRefs; the argument
should be a constant C-string.
CFSTR(), not being a "Copy" or "Create" function, does not return a new
reference for you. So, you should not release the return value. This is
much like constant C or Pascal strings --- when you use "hello world"
in a program, you do not free it.
Where as the object you create with CFNumberCreate will be owned by the caller so you may still want to keep the word create in the name to make this clear.
You could always make a helper function just to avoid passing the same arguments over and over
CFNumberRef PSNumberCreateWithChar(x)
{
return CFNumberCreate(kCFAllocatorDefault, kCFNumberCharType, &x);
}
CFNumberRef and NSNumber are toll free bridged so you can use the NSNumber literal syntax and cast the result.
I have recently started programming in iOS.. I am going through a code snippet that declares the following variables:
int rc = 0X00;
sqlite3_stmt *pStmt = 0X00;
FMStatement *stat = 0X00;
BOOL abc = 0X00;
what does this mean?? I read somewhere that setting 0X00 in a reference variable means setting it to NULL (in C). But what does setting a BOOL type variable and an int type variable to 0X00 mean??
I suggest you read up about the basics of programming languages, specifically, C programing with pointers. Objective-C is a superset of C and follows many similar rules.
But to your question:
The 0x in front of the literal values in the code (0x00) specifies that the value is interpreted as hexadecimal rather than decimal. But 0x00(hex) is the same as 0(dec).
int rc = 0x00; //same as int rc = 0;
int is a primitive type in both Obj-C and C that specifies an integer, effectively you are initializing the variable. In the C language you must initialize variables otherwise they could be pointing at a random piece of memory.
Therefore, examine this code:
int a;
int b = 0;
//a is NOT equal to b!
In C, the variable 'a' has not be initialized and therefore its not typically safe to assume that it will be initialized to 0. Always initialize your variable.
If you did a printf, or an NSLog of the variable 'a' you will see that it prints some huge number and it doesnt make sense (sometimes this is compiler dependent)
The same can be said for a BOOL. Although setting a BOOL to 0 is the same as setting it to false;
BOOL flag = 0; //The same as saying BOOL flag = false;
Now for the final part of your code:
FMStatement *stat = 0X00;
Often in Objective-C if you are dealing with pointers and objects you need to initialise the pointer to point at some memory address. The actual memory address is usually determined by the stack/heap and you don't need to worry about that. But you do need to ensure that the pointer isn't pointing to the wrong location (known as a garbage pointer).
To do this, we simply set our pointer to nil. eg:
FMStatement *stat = nil; //This pointer is now safe. Although memory still hasnt been allocated for it yet
This is usually taken care of for you though when you immediately allocate the memory for an object, therefore in this case you don't need to worry about initializing the pointer to nil:
FMStatement *stat = [[FMStatement alloc]init];
Like I said, I recommend you read about basic C programming, allocations, pointers, datatypes, initialising etc, once you have a grasp of this, then move to Objective-C which then builds ontop of it with Object-Oriented stuff.
Good luck.
0X00 is simply 0 in hexadecimal notation. So,
int rc = 0X00;
is the same as
int rc = 0;
Same for BOOL variables, where 0 is the same as NO. Using 0X00 is odd -- it'd make more sense to use 0 or NO where appropriate, and use nil for the pointers.