0

char array's are actually pointers

This is a common misconception. An array is not a pointer, but when used in value context, the name of an array is converted to a pointer to the first element in the array. In object context, the name of an array is not converted, such as as an operand to the sizeof operator.

2

... or use bitwise operator if(i&1) if true even else odd.

I suppose if you want readers of your code to think you're clever, or have legitimately profiled the code for performance, run all practical test cases, and determined that this micro-optimization is warranted and not actively harmful.

Its faster because compare one bit only without mathematics

Citation needed. Compilers are rather smart, often smarter than the programmers who merely think they're smart. Optimizing x % 2 into the suitably fast machine code is rather trivial. If you're applying this optimization with expectations of any noticeable positive impact, I think you'll be disappointed.

In fact, trying to outsmart the compiler can indeed produce slower machine code by bypassing superior optimizations. If it does improve performance for your test cases, there's a good chance the compiler explicitly chose not to optimize it because the results would be flat out wrong.

But let's not quibble over minutia. Instead, how about looking at a far more sinister problem with your suggestion: x & 1 is not synonymous with x % 2. On top of limiting the supported type to integers, the result of the operation varies between the two when working with signed integers. Will it work? Probably...but are you sure? Note that the OP's code is performing this check on values contained in an array. These values will likely eventually be uncontrolled user input. Are you still sure it will work correctly? Can you prove it?

It's unfortunate that these ...

Votes + Comments
Good point.
3

Thus c_str() isn't making a copy of anything, globalPtr is pointing to the same array of characters that abc uses and if you make a change using globalPtr or abc, both are affected.

Yup, c_str isn't required to make a copy of anything, and usually doesn't.

returnValue seems to point to I'm not sure where, but clearly it's not pointing to whatever c_str() returned?

returnValue points to the internal buffer of the string object. VS2015's string class maintains a null terminator in the internal buffer to facilitate simple logic for c_str. The destructor also shrinks the string to zero length, which leaves the released memory clean and explains why the output is "" rather than the previous contents of the string.

I'd suspect GCC "works" because it doesn't have this cleaning step, so whatever was at that memory location remains the same while it "fails" with VS2015 because of the truncation in the destructor. Regardless of compiler quirks, the code exhibits undefined behavior due to accessing memory you don't own.

So, calling c_str() is perfectly fine?

Yes.

if temporary object won't exist after enclosing braces of fun(), then callingc_str() should also be wrong. Isn't it?

It would be if the braces of fun() were the sequence point I mentioned. Instead it's the full expression of returnValue = fun().c_str(). When the initialization of returnValue is complete, the temporary is destroyed, not before.

Secondly, when exactly the temporray object be destroyed?

The rules are somewhat complex, but ...

Votes + Comments
Awesome :)
Good explanation
1

when fun() returns, it calls the copy constructor again, right?

Ehh, kind of. Return value optimization is a thing, but conceptually it's okay to think of things that way for simplicity.

But, won't it call the copy constructor and then make the copy of the object and return it to the returnValue variable?

Yes, but the lifetime of that temporary object ends after the enclosing expression's sequence point. The enclosing expression is your initialization statement for returnValue, which is why you can call c_str successfully (ie. the temporary object still exists), but the pointer is dangling at the end of the statement (where the temporary is destroyed), because it points into the temporary object's memory rather than directly owning the memory.

Boiled down, the problem is really no different from returning a pointer to a local variable even though throwing unnamed temporaries into the mix makes it harder to recognize.

Votes + Comments
+1
2

Can you please explain the reason behind this?

You're capturing a direct pointer to the internal storage of the string returned by fun(), which is a temporary object. The temporary object is subsequently deconstructed, and the internal storage goes away. I'd suggest stepping into everything in the debugger to see how your compiler is handling the objects, because this is correct behavior.

returnValue2 works fine as you're copying the temporary object and preserving its contents in a new object.

Votes + Comments
+1 for to-the-point answer
1

I agree with AssertNull, it's very likely the newline character mucking things up. Your compiler (or compiler settings) probably aren't zeroing out local variables while AssertNull's is, which explains the code working in one place but not another. You can verify this by initializing _artichoke, _beet, and _carrot to 0.

Typically, it's not wise to mix formatted and unformatted input (ie. getchar and scanf) due to differences in handling of whitespace. IIRC, the %d format modifier should skip whitespace before attempting a character extract, though I don't recall if that's a hard requirement or just something that a lot of compilers do (it's been a while since I read the standard ;p). You can force it by putting a leading space in your format string:

scanf(" %d", &_artichoke);

fseek(stdin,0,SEEK_END);

Yeah, that's not guaranteed to work. There's not a complete standard way to "flush" stdin in C; the best you can get is some variation of this:

int c;

do
{
    c = getchar();
} while (c != '\n' && c != EOF);

It's perfectly functional, provided the stream is not currently empty. If it is empty, getchar will block for unnecessary input and there's no standard way to get around that particular issue.

2

What am I missing here?

Two things:

  1. Student s(pName) is creating a variable called s via the const char* constructor of the Student class. I get the impression you're confusing this with a function declaration given your mention of a "variable name".

  2. You can generally add a const qualifier without issue, but it cannot be removed without a cast. This is what the book is explaining. pName does not have a const qualifier, but it can be safely passed to the Student constructor that expects a const qualifier. This qualifier will be added for you automagically and the parameter to the constructor will be treated as const.

The code isn't ideal, of course. pName should be declared as const to avoid subtle issues which could arise depending on how the constructor uses the pointer.

Votes + Comments
Good explanation.
0

Not a strange question at all, and we got it quite often when the TOS explicitly claimed copyright to any posts made (it doesn't appear to do so any longer).

In the past, ownership of post content was in practice only to absolve us of responsibility for storing, editing, and deleting posts as necessary under the rules, and any IP for purposes of external copyright would still be happily relinquished by Dani and Daniweb LLC. But legally, you'd still need to request it.

Now it's not so clear, but without any claim of copyright, I'd lean toward default ownership of any IP going to the original author being how the law works. That's my interpretation, of course. I'll let Dani confirm or deny my assumptions. ;)

1

It could be the Framework or it could be how it has been implemented by my predecessor

It's the latter, almost surely. The Entity Framework most certainly has its quirks, but being unstable and slow are not among them when used properly.

So I'm wondering if there is a way to just take the entity part out and build an old fashioned data layer with views and stored procedures...

It rather depends on the design, and I suspect the design is fairly entrenched in EF weirdness. My personal preference is to use more of an ADO.NET approach with EF to facilitate database compatibility, but that's not really at issue here. I suspect you're stuck optimizing a poor design. Sorry.

5

or cracker are going to crack it easier, steal people's data and people will start disregarding software as unsafe.

Here's my take on it: insecure software will be insecure regardless of code availability. Open source certainly makes insecure software easier to crack, but the underlying problem isn't being open source, it's being insecure.

The fix is not to implement security by obscurity and hope crackers aren't smart enough to dig into the binaries, the fix is to correct security holes. And for that goal, open source is potentially superior as there can be more eyes on the code.

1

I think this is an old micro-optimisation thing that is irrelevant with modern compilers.

It was irrelevant even in prehistoric times too, unless you were working with one of the dumbest compilers ever. Even Dennis Ritchie's first C compiler performed this optimization.

However, note that the type of i matters. For int (or any built-in type, generally), the two are functionally identical. For class types that overload the ++ operator, the prefix version will likely be slightly more efficient.

0

The auto keyword is compiler magic from C++11 that interprets the type of a variable from its initializer. It's not a dynamic type or anything, so as an example if you're using v.begin() as the initializer, auto will choose the type of the collection's non-const iterator (in this case vector<vector<double> >::iterator). Really the only difference is you don't have to manually use the type name or worry about changing any use of it if the if the type changes.

1

is there no such thing for Windows?

It depends on the IDE being used and how it handles program output. I'd be surprised if there weren't an IDE that allows you to display output in a tool window like XCode. Typically you'd have your program open in a new console window for testing, is that not sufficient for your needs?

That said, you can do this with Visual Studio after a fashion.

  1. In VS, navigate to Tools | External Tools.
  2. Click the Add button.
  3. Under the Title field, type something like Console.
  4. Under the Command field, type cmd.exe.
  5. Under the Arguments field, type /c $(TargetPath)
  6. Check the Use Output window option.
  7. Hit OK to save the new tool.

Now Console is available from the Tools menu, and you can add a button to your toolbar that activates it easily to execute your latest build and redirect stdout to the Output window.

There may be an easier way to do this, but I don't know it.

1

Forget that you're dealing with miter->second for a moment. How would you display the contents of a vector? We know cout doesn't have an overloaded << operator for collections, so you're stuck with some variant of a loop. This comes immediately to mind:

for (auto it = v.begin(); it != v.end(); ++it)
{
    cout << *it << ' ';
}

Since this is a vector of vectors, you have a nested loop:

for (auto row = v.begin(); row != v.end(); ++row)
{
    for (auto col = row->begin(); col != row->end(); ++col)
    {
        cout << *col << ' ';
    }

    cout << '\n';
}

Now replace v with miter->second, as that's your reference to the mapped vector object.

The idea here is to start with something you understand, then add complexity until you have the final solution that you're looking for.

0

I've never used C++/CLI, but it looks like std::string is a distinct type from System::String and presumably Console::WriteLine only works with the latter as it is a .net method and std::string is a C++ class.

Correct. System::String^ is a managed reference type which is not directly compatible with std::string.

Presumably C++/CLI offers some way to convert between the two string types, but I imagine in this case it'd be easiest to just either only use C++ strings and C++ IO functions or .net strings and .net IO functions.

Yes, and agreed. There's a method to convert between the two, but it's awkward enough that it should be avoided where possible.

Results in: Error 1 error C1083: Cannot open include file: 'stdafx.h': No such file or directory. The funny answer I got is "just delete it"... but it's not even there and it isn't even included.

Visual Studio is stupid like that. If you generate a console project, stdafx.h will be generated as well, along with a switch in the project settings saying to expect it. For this reason I strongly recommend starting with an empty project instead, because it saves you from having to dig into project settings to fix things like this as well as delete any autogenerated kruft.

Is there no way to program standard C++ CLI applications without having this ".NET CLR"?

No.