- Seems like the double * and double ** are put on stack in reverse order expected - 6 Updates
- Declare function in C++ - 4 Updates
- How to replace Umlauts? - 8 Updates
Bob Langelaan <bobl0456@gmail.com>: Apr 16 02:15PM -0700 This output below is produced using MS VS 2105 in Release mode. Any idea as to why it appears that the double ** variable is put on stack before the double * variable ? Program: #include <iostream> using namespace std; int main() { double myArray[10]; // define an array of 10 doubles cout << "Address of myArray is: " << myArray; double * dblePtr; // define a pointer to double double ** dblePtrToPtr; // define a pointer to a pointer of type double cout << "\n\nAddress of dblePtr is: " << &dblePtr; cout << "\n\nAddress of dblePtrToPtr is: " << &dblePtrToPtr; cout << "\n\nSize of dblePtr: " << sizeof dblePtr; cout << endl; return 0; } OUTPUT: Address of myArray is: 0033FE10 Address of dblePtr is: 0033FE08 Address of dblePtrToPtr is: 0033FE0C Size of dblePtr: 4 Press any key to continue . . . |
jt@toerring.de (Jens Thoms Toerring): Apr 16 09:54PM > Address of myArray is: 0033FE10 > Address of dblePtr is: 0033FE08 > Address of dblePtrToPtr is: 0033FE0C Why do you care? There's no rule in the standard that would require the compiler/linker to put the variables in any order into memory (and if you hadn't printed the addresses they may even never have been in memory at all but just in CPU registers)? All this is absolutely at the discretion of the compiler and using different compiler flags or a different version could re- sult in a completely different picture. To be honest, being curious I have done the same kind of tests more than once;-) And in most cases (not with MS VS) the results were similar. Since I haven't looked at the compilers sources I can only guess: the parser uses a stack onto which it pushes each variable to be defined. And when the end of the function is reached it makes room for them, popping them from the stack, so the last one defined becomes first one on the programs stack. But that's pure guesswork and not backed by any hard facts! Regards, Jens -- \ Jens Thoms Toerring ___ jt@toerring.de \__________________________ http://toerring.de |
Bob Langelaan <bobl0456@gmail.com>: Apr 16 03:14PM -0700 On Saturday, April 16, 2016 at 2:54:18 PM UTC-7, Jens Thoms Toerring wrote: > -- > \ Jens Thoms Toerring ___ jt@toerring.de > \__________________________ http://toerring.de Thanks for your reply. Can I assume if instead of defining pointers we were defining objects with associated dtors, that they would always be put on the stack in the expected order to ensure that the dtors are invoked in the correct order? |
Barry Schwarz <schwarzb@dqel.com>: Apr 16 03:57PM -0700 On Sat, 16 Apr 2016 15:14:31 -0700 (PDT), Bob Langelaan >> \__________________________ http://toerring.de >Thanks for your reply. >Can I assume if instead of defining pointers we were defining objects with associated dtors, that they would always be put on the stack in the expected order to ensure that the dtors are invoked in the correct order? I doubt it. What is the relationship you see between location and invocation? -- Remove del for email |
Paavo Helde <myfirstname@osa.pri.ee>: Apr 17 02:03AM +0300 On 17.04.2016 1:14, Bob Langelaan wrote: >> \__________________________ http://toerring.de > Thanks for your reply. > Can I assume if instead of defining pointers we were defining objects with associated dtors, that they would always be put on the stack in the expected order to ensure that the dtors are invoked in the correct order? Order of destruction is guaranteed by the standard, but this has nothing whatsoever to do with the addresses of the variables in memory. In particular, in your example there are no destructors involved; the results might be different if you used objects with real destructors. hth Paavo |
jt@toerring.de (Jens Thoms Toerring): Apr 16 11:05PM > Can I assume if instead of defining pointers we were defining objects with > associated dtors, that they would always be put on the stack in the expected > order to ensure that the dtors are invoked in the correct order? Sorry, but you can't. The compiler can, more ore less, put any object whereever it likes. Actually, neither the C nor C++ stan- dard even mandate that there's a stack at all, so how could be there a requirement on how things have to be organized on the stack? And what is an "expected order"? I have no idea what that would be. Please take a step back and tell what you want to achieve by re- lying on some objects being ordered in a certain way on the stack. You may get away with that with a certain version of a compiler, when using a certain set of compiler flags, on a certain version of an operationg system. But any small change in any of these parameters may invalidate everything that you may have found out about the compilers behaviour experimentally. Better stay away from that unless you have very, very good reasons to do it any- way. Regards, Jens -- \ Jens Thoms Toerring ___ jt@toerring.de \__________________________ http://toerring.de |
Kalle Olavi Niemitalo <kon@iki.fi>: Apr 16 05:02PM +0300 > What do you mean by "cannot modify the class"? In C++11, a const member function of a class cannot cause that class to become derived from additional base classes. #include <iostream> #include <type_traits> class A { }; class B { public: template<typename base> void add_base() const {} }; int main() { std::cout.setf(std::ios_base::boolalpha); // This outputs "false" because B has no base classes. std::cout << "Is A a base class of B? " << std::is_base_of<A, B>::value << std::endl; // Try to add A as a base class of B. // However, add_base<A> is a const member function, // so it cannot actually add base classes to B. B().add_base<A>(); // This outputs "false" again because the base class was not added. std::cout << "Is A a base class of B now? " << std::is_base_of<A, B>::value << std::endl; } // ;) |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 16 08:04PM +0200 On 16.04.2016 16:02, Kalle Olavi Niemitalo wrote: >> What do you mean by "cannot modify the class"? > In C++11, a const member function of a class cannot cause that > class to become derived from additional base classes. ↑ nonsense. |
Kalle Olavi Niemitalo <kon@iki.fi>: Apr 16 10:10PM +0300 >> In C++11, a const member function of a class cannot cause that >> class to become derived from additional base classes. > ↑ nonsense. Well spotted! The inability to add a base class to class B at run time had nothing to do with const vs. non-const member functions. The real reason for class B not being polymorphic was that it neither declared nor inherited any virtual functions. ;) Seriously, I also tried to use SFINAE to select different base classes for class B depending on whether class B has a member function with a particular name -- which could then be further constrained to be a const member function. I believe it is impossible because class B is incomplete when the compiler is figuring out its base classes. Besides, it would lead to a paradox if class B inherits a function with that name from a base class that was selected because class B had no such function. |
Kalle Olavi Niemitalo <kon@iki.fi>: Apr 17 12:08AM +0300 > ting to objects, that can not be changed when the pointer is a > member of a const qualified class instance, and one for pointers > as we have them now. That apparently cannot be implemented as a smart pointer template because the constructors cannot be overloaded according to whether the object being constructed is const or not. template<typename T> class propagating; template<typename T> class propagating<T *> { T *p; public: propagating(T *v): p(v) {} T &operator *() { return *p; } const T &operator *() const { return *p; } // C++ does not support this kind of overloading: // propagating(propagating &) = default; // propagating(propagating &) const = default; // propagating(const propagating &) = delete; // propagating(const propagating &) const = default; }; struct X { propagating<int *> p; }; int main() { int i1 = 1; const int i2 = 2; X x1 { &i1 }; // allowed, as intended *x1.p = 0; // allowed, as intended const X x2 { &i2 }; // error, but should be allowed *x2.p = 0; // error, as intended X x3 = x2; // allowed, but should be rejected... *x3.p = -1; // ...because it permits this write to i2 const X x4 = x1; // allowed, as intended } If that kind of overloading were allowed, then [dcl.fct] would have to be modified not to delete top-level cv-qualifiers of parameters in function declarations like void f1(X x); void f2(const X x); because it should be possible to call f2(x2) but not f1(x2). |
"Heinz-Mario Frühbeis" <Div@Earlybite.individcore.de>: Apr 16 04:54PM +0200 Hi, I have an issue with XDrawString from XLib, because it prints only special characters instead of ü, ö, a.s.o. E.g.: string test = "Hüh"; XDrawString(..., test, ...) // isn't printing ü But what works is: string test = "h"; char nChar = (char) 252; // is ASCII ü test = test + nChar; test = test + "h"; XDrawString(..., test, ...) // is now printing ü So I wanted to replace ü with (char) 252... But I do get it working, this is one of my tries: strimg nCaption = "ausführen"; if(nCaption != ""){ if(nCaption.find("u") > 0){ char nChar = (char) 252; const char* nChar1 = &nChar; std::string umlaut = "ü"; nCaption.replace(nCaption.find("ü"), umlaut.length() , nChar1); } } The error is: terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::replace Can someone please help me out? Regards Heinz-Mario Frühbeis |
Kalle Olavi Niemitalo <kon@iki.fi>: Apr 16 07:46PM +0300 > const char* nChar1 = &nChar; > std::string umlaut = "ü"; > nCaption.replace(nCaption.find("ü"), umlaut.length() , nChar1); I'm not sure why it'd throw std::out_of_range but that code has at least one bug: because nChar1 is a const char*, the replace function assumes it points to a null-terminated string but you didn't put any null character there. Also, if basic_string::find doesn't find anything, it returns npos rather than 0. You could do it this way instead: const string umlaut = "ü"; for (string::size_type pos = nCaption.find(umlaut); pos != string::npos; pos = nCaption.find(umlaut, pos + 1)) { nCaption.replace(pos, umlaut.length(), 1, (char) 252); } (Using pos + 1 in the second find call to prevent an infinite loop if "ü" is "\xfc" in the execution character set.) However, a proper solution would convert all characters to the correct encoding, rather than only "ü". Which font are you using in X11? AFAIK, X11 core text requests are not recommended nowadays, and toolkits use X Rendering Extension instead. http://www.x.org/wiki/Development/X12/#char2b |
jt@toerring.de (Jens Thoms Toerring): Apr 16 05:22PM > But what works is: > string test = "h"; > char nChar = (char) 252; // is ASCII ü That's where things start to go wrong: there is no 'ü' in ASCII - ASCII defines only the values up to 127 (ASCII is an abbreviation for American Standard Code for In- formation Interchange and the Americans don't use um- lauts and, moreover, back when it was designed it wan't uncommon to use only 7 bits for representing characters). There are lots of different encodings that use the values above 127, one of them being 'iso_8859-1' (commonly used for Western European languages) and that's probably the one you got the idea from the the 'ü' is represented by the value 252 (same in a number of other iso_8859-x encodings but not all of them - in the encoding used for Cyrillic, 'iso_8859-5', 252 represents 'ќ'). And XDrawString() will render that value as 'ü' only if you also use a font that is made for these encodings. Next problem: if you have > string test = "Hüh"; in your code then what is stored in 'test' depends on what encoding your editor uses. Nowadays it's not unlikely that this is UTF-8 and, if you look at the individual bytes, e.g. by going through 'test.c_str()', you will find that it con- tains 4 chars, the first one being 0x48, the second 0xC3, the third 0xBC and the fourth 0x68. The 0x48 and 0x68 are 'H' and 'h' as in ASCII (ASCII characters, i.e. stuff up to 127 are encoded the same way in UTF-8) and the combination of 0xC3 and 0xBC is the way UTF-8 encodes 'ü', officially called "LATIN SMALL LETTER U WITH DIAERESIS". If you use a font for iso_8859-1 encoding XDrawstring() will render them as 'Ã' and '¼', but if you'd use a UTF-8 font it would be ren- dered as 'ü'. It gets trickier when you use input coming from outside the program: what you will read depends on the encoding used by whatever sends the data - if you e.g. try to draw strings entered into a terminal what 'test' will contain depends on what encoding the terminal uses. And if you use input you got from Xlib functions things get even a bit more "intereting". > XDrawString(..., test, ...) // is now printing ü > So I wanted to replace ü with (char) 252... > But I do get it working, this is one of my tries: Well, it works somehow because you use a (probaby) iso_8959-1) font and forced the value of 252 into the string (and std::sstring doesn't care at all about the encoding, you can actually store any binary data in a std::string. And the length method doesn't tell you how many "letters" there are since that would depend on how letters are encoded but just the plain number of bytes. The following is for sure not the code you're using (it won't even compile), so anything one can say about it may have nothing to do with the problems you're facing... > strimg nCaption = "ausführen"; ^ > if(nCaption != ""){ What's that test for - the find() method of std::string will work quite fine on an empty string? And why, if you insist on this test, not use the empty() method? > if(nCaption.find("u") > 0){ Why do you look for "u" in the string? And the find() method does return the position of what you where looking for, which can include 0 (the very start of the string). What you should ompare to is std::string::npos which is what gets returned if the string does not contain what you were looking for. So your test asks: is there an "u" somewhere in the string beyond the first byte or non at all? What you need here is if (nCaption.find("ü") != std::string::npos) to make sense since it asks: is there an "ü" in that string? > const char* nChar1 = &nChar; > std::string umlaut = "ü"; > nCaption.replace(nCaption.find("ü"), umlaut.length() , nChar1); The third argument to the replace() method must, when you call it with a char pointer, be a pointer to a C string (which must include a '\0' at the end!), but what you pass it is a pointer to a single char with no '\0' following it (or only just by chance). Be prepared for lots of strange looking stuff to get inserted for the 'ü'... > } > } All that could have been written much simpler and cleaner as std::string nCaption = "ausführen"; const char iso_8859_1_uuml[] = {252, '\0'}; const size_t len = std::string("ü").length(); size_t pos; while ((pos = nCaption.find("ü")) != std::string::npos) nCaption.replace(pos, len, iso_8859_1_uuml); But that only "solves" the problem for 'ü', you've got to do the same replacements for all non-ASCII characters you're pre- pared to deal with (and decide what to do with those that can't be represented in your choosen encoding)... And if you switch to a font that's made for UTF-8 this will actually break things. Regards, Jens -- \ Jens Thoms Toerring ___ jt@toerring.de \__________________________ http://toerring.de |
"Heinz-Mario Frühbeis" <Div@Earlybite.individcore.de>: Apr 16 07:51PM +0200 Am 16.04.2016 um 18:46 schrieb Kalle Olavi Niemitalo: > pos = nCaption.find(umlaut, pos + 1)) { > nCaption.replace(pos, umlaut.length(), 1, (char) 252); > } This is working. Thanks! I still have an issue with string, char, 0-byte /yes/no. I think, you know what I mean. I'm coming from VB6 for over 20 years, and with C++ and GNU/Linux I'm now working for ~ 2 years. > However, a proper solution would convert all characters to the > correct encoding, rather than only "ü". Which font are you using > in X11? I'm using different fonts... And the program can change the font while runtime. > AFAIK, X11 core text requests are not recommended nowadays, > and toolkits use X Rendering Extension instead. > http://www.x.org/wiki/Development/X12/#char2b I'm not sure if I know what you mean... Currently I use the XLib and XListFonts, so I have many 'misc', some 'schumacher', and less 'sony'. AFAIK will those fonts run on every GNU/Linux... Maybe later I will implement other fonts too, but for now it is OK for me. Thank you very much for your help! Regards Heinz-Mario Frühbeis |
"Heinz-Mario Frühbeis" <Div@Earlybite.individcore.de>: Apr 16 07:56PM +0200 Am 16.04.2016 um 18:46 schrieb Kalle Olavi Niemitalo: > AFAIK, X11 core text requests are not recommended nowadays, > and toolkits use X Rendering Extension instead. > http://www.x.org/wiki/Development/X12/#char2b Maybe an AddOn-question: How do you handle e.g. a 10 pages , or even a 100 pages document? Does it really need to parse them in this way? Regards Heinz-Mario Frühbeis |
Kalle Olavi Niemitalo <kon@iki.fi>: Apr 16 11:10PM +0300 > I'm using different fonts... > And the program can change the font while runtime. XCreateFontSet + either XmbDrawString or Xutf8DrawString seems the best solution, as long as you're using X11 core text. Then your program doesn't itself have to convert the strings to the encoding of the font. |
jt@toerring.de (Jens Thoms Toerring): Apr 16 08:24PM > Maybe an AddOn-question: > How do you handle e.g. a 10 pages , or even a 100 pages document? > Does it really need to parse them in this way? I'm not really sure what this question means. If you need to re-encode something, then yes, something has to run over all of it and do the conversion. But, of course, it doesn't have to be your program that does it again and again if this is about some text that you read in from some file. There are tools for re-encoding, the usual suspect being 'iconv'. If you want to convert some file from say UTF-8 to ISO_8859-1 you'd do iconv -f UTF-8 -t ISO_8859-1 -o outputfile inputfile Use 'iconv -l' to get a list of all encodings known to to it (there are more than 1000;-) Of course, there are limits: if the file in its source encoding contains characters that don't exist in the target encoding then there's nothing useful it could do and it will complain about an "illegal input sequence" at the first character that can't be con- verted). And then there's libiconv that you can use within your program to do re-encodings (though it's a C library, but there's also a C++ wrapper for it, called 'iconvpp', and available on github). Regards, Jens -- \ Jens Thoms Toerring ___ jt@toerring.de \__________________________ http://toerring.de |
"Heinz-Mario Frühbeis" <Div@Earlybite.individcore.de>: Apr 16 10:33PM +0200 Am 16.04.2016 um 22:10 schrieb Kalle Olavi Niemitalo: > the best solution, as long as you're using X11 core text. > Then your program doesn't itself have to convert the strings > to the encoding of the font. I will have a look on it. Thanks. Regards Heinz-Mario Frühbeis |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment