|
I will not change existing code; it's just too dangerous.
I'm just curious; if there's a best practice.
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
My best practice doesn't fit either of your suggestions...
If I am creating a new database layer (which I have numerous times) then the caller would never provide the SQL.
If the business layer(s) need new database logic then the database layer should be modified to provide it.
The caller provides the parameters that would be used in the call.
Then within that database layer method it would decide how to process the parameters and SQL (provided by the method.)
So it looks like the following.
void DatabaseDoX(param1, param2,...)
{
std::string fullyFormedQuery = sprintf (SQL_X, param1, param2, ... );
There are quite a few variations on the above. For example consider the complication of a user initiated call where they might specify different 'query' terms (like data range, customer name, etc)
But all still hide the SQL.
Certainly there are design considerations for example your code might be coming from within the database layer (not a business call at all.) If so then I suspect that usage would actually vary depending on what the database layer was specifically doing in the code path.
|
|
|
|
|
I was playing around in Microsoft Visual C++, and I noticed something weird about this code:
void setname(char name[80])
{
strcpy_s(name, "joebob");
char name2[80];
strcpy_s(name2, "joebob");
}
It looks like the compiler complains about the first strcpy_s but not the second one. If I comment out the first one, the program compiles fine.
Can anyone explain this?
BTW, I know strcpy_s should probably take 3 arguments, but I'm trying to understand this weirdness.
Thanks.
|
|
|
|
|
Remember that in C arrays and pointers are the same thing so the argument name is a pointer to char. For the compiler, your code fragment is the same as:
void setname(char *name)
{
strcpy_s(name, "joebob");
char name2[80];
strcpy_s(name2, "joebob");
} In the case of the second call to strcpy_s , the compiler can figure out the size parameter through some template magic. For the first one however you have to use the explicit size form.
Mircea
|
|
|
|
|
It would help when posting questions that you include the exact error message(s), so it makes it clear what your problem is.
|
|
|
|
|
|
Should this work in C++?
long add1(a)
long a;
{
return a+1;
}
It doesn't seem to compile in Visual Studio. I got it from MIT's OpenCourseware.
Thanks.
|
|
|
|
|
That is the so called K&R syntax[^]. You can compile as C code but not as C++. The C++ version would be:
long add1 (long a) {
return a+1;
}
Mircea
|
|
|
|
|
mike7411 wrote: I got it from MIT's OpenCourseware.
I see the MIT is still at the cutting edge of technology !!
CI/CD = Continuous Impediment/Continuous Despair
|
|
|
|
|
I am a little confused about when to use delete and delete[].
Is this correct?
int* numArray = new int[100];
delete numArray;
Or should it be this?
int* numArray = new int[100];
delete[] numArray;
I saw the former in an MIT lecture, and it looked suspicious. Both of them compile.
Thanks.
|
|
|
|
|
If you create an array with operator new as above, then you must tell delete that it is an array. So example 2 is the correct way to do it.
|
|
|
|
|
Array delete operator, delete[] invokes the destructor of each array element before freeing the array. For an array of integers, it doesn't make any difference. Meanwhile, if the objects in the array have a non-trivial destructor you should call the delete[] operator.
Mircea
|
|
|
|
|
Mircea Neacsu wrote: For an array of integers, it doesn't make any difference.
It is true that no destructor is called for each element of an int[] array, but that does not mean that the memory layout is compatible with delete. For example, the compiler might allocate additional space for a variable containing the size of the array and return a pointer to memory after this variable. When using delete, the heap will be corrupted.
The heap layout is implementation-dependent, and therefore you should always match new/delete and new[]/delete[]!
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
While you are absolutely right, I don't know of any heap manager that behaves the way you describe. Let's say that calling delete on an int array is a smaller sin, a "peccadillo" that will place you on one of the first circles of hell.
Mircea
|
|
|
|
|
As noted you should use the correct one.
I know for a fact that long ago using the wrong one would cause memory stack corruption.
I presume that now that isn't possible or is less likely.
Although I would be curious if the spec deals with that specific issue.
|
|
|
|
|
In any case, smart pointers are preferable in almost all cases to new/delete. I imagine that there are some cases where new and delete are preferred to smart pointers, but for most applications, a smart pointer is the better option.
"A little song, a little dance, a little seltzer down your pants"
Chuckles the clown
|
|
|
|
|
I'm using NtQueryInformationProcess [^] to find the parent process of a specified process. I'm passing a PROCESS_BASIC_INFORMATION structure and using the InheritedFromUniqueProcessId member to get the parent.
I then call this function recursively with each parent process to find the parent of the parent, and so on.
The problem is that sometimes it starts returning process IDs that it has already returned in earlier calls, leading to infinite recursion.
For instance, in successive calls it will return process IDs 3, then 2, then 1. Then when called for process ID 1 it will return 3 again! How can this be?
I can easily work around this by checking to see if the returned parent process ID was already returned earlier in the call stack, and if it was, breaking out of the loop.
But my question is, why?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Dynamic versus static structures? Different types of parents / qualifying information?
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Can you elaborate? I didn't know there were different types of parents. And I don't know what you mean by dynamic versus static structures.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
If I'm climbing a tree and the branch I'm climbing gets moved, what am I climbing?
I child can have multiple parents. You need to know which parent you're dealing with. If they inherit the same base, they "look" the same but aren't.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
I don't see how a process can have more than one parent process. This is something I hadn't considered.
If Process A calls CreateProcess and launches Process B. Then A is the parent. I don't see how any other process can be a parent of B.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Some sort of circular dependency? You see a similar behavior if you've ever used Dependency Walker.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
Yes I see what you're saying. The only kind of dependency that I am familiar with is the static kind used by DLLs.
What kind of dependency are you discussing?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
I have seen that also. Annoying when it showed up an I always ignored it without considering the reason why.
|
|
|
|
|
Seems like an interesting question.
Googling I found nothing that answers that.
From the other post I did find a comment in 'Dependency Walker' but that only stated that it occurred but not why.
Maybe you could determine the cause by looking at the detailed process information and comparing them?
|
|
|
|