Re: Making a struct field constant, when this struct is imported to a particular Cpp files
Hi Ansis, first: you should use gcc-h...@gcc.gnu.org for questions like this... On Thu, Nov 12, 2009 at 05:44:58AM -0800, ansis atteka wrote: > I have a struct in a header file. And I would like to have some of this > struct member fields to be constant, in case if this header file is included > from some particular Cpp files. Motivation for this is to avoid some silly > programmer errors by accidentally writing to this variable, when developer > is not supposed to do that. I guess that it is possible to catch these > errors already at the compile time with a const keyword. > > I already have approach, but I am not quite sure whether it is > safe(especially regarding the compiler optimizations). Below are uplaoded > files. > > In this case util.cpp is not allowed to edit S.y contents, while rw.cpp is > allowed to do that. File h.hpp contains the struct which is customized at > the preprocessor execution time by looking at the READONLY define. > > If this is not safe, are there any other approaches? I am afraid that > compiler might optimize out something. Assumption is that other threads will > not touch this member. > > Regards, > Ansis > > http://old.nabble.com/file/p26318895/Makefile Makefile > http://old.nabble.com/file/p26318895/rw.cpp rw.cpp > http://old.nabble.com/file/p26318895/h.hpp h.hpp > http://old.nabble.com/file/p26318895/util.cpp util.cpp > http://old.nabble.com/file/p26318895/util.hpp util.hpp > Yes, this approach is save. However, some minor remarks: - I'm not completely sure whether the position of "-DONLY_READ" is important for some versions of gcc ??? - it is safer, when you write it as argument before the first file: g++ -O3 -DONLY_READ -c util.cpp -o util.o - instead of using "-DONLY_READ" in the makefile it might be easier to use "#define ONLY_READ" inside the cpp-File - before including h.hpp: #define ONLY_READ #include "util.hpp" That creates exactly the same code. - The code might be easier to understand if you write: ONLY_READ int *y; instead of #ifdef ONLY_READ const int * y; #endif #ifndef ONLY_READ int * y; #endif inside h.hpp, and "#define ONLY_READ const" in all cpp-Files where you want it to be constant (util.cpp) and "#define ONLY_READ " in all cpp-Files, where you want read-access (rw.cpp). These defines have to be before the #include-Command. - if you use "ONLY_READ int *y;", you can also try #ifndef ONLY_READ #define ONLY_READ #endif ONLY_READ int *y; in the header-file h.hpp. This allows to include without "#define ONLY_READ": - if "ONLY_READ" is not defined, you get read-Access - if "ONLY_READ" is defined as "const", you have constant access. Axel
Re: Possible bug: Template name lookup & overloaded functions.
Hi On Mon, Jan 18, 2010 at 10:37:34PM +1300, Simon Hill wrote: > http://www.gamedev.net/community/forums/topic.asp?topic_id=559287 > > SOURCE > > template > void foo(pTYPE arg) > { arg.nid(); } > > template > void bar() > { > pTYPE var; > foo(var); > } > > void foo(int) > {} > > int main() > { > int i; > foo(i); // OK: Resolves foo(int). > bar(); // ERROR: Fails to resolve foo(int). > } > === > > It seems to me now that this is a bug with GCC. > Can someone confirm this please? Well, I think g++ behaves correctly. As I understand the standard, the normal function foo(int) can't be used in the template "bar", because it is only declared afterwards. In "main", when foo is called directly, that's no problem: there, foo and foo(int) are both declared already. If you write: te void foo(pTYPE arg) { arg.nid(); } void foo(int) {} template void bar() { pTYPE var; foo(var); } int main() { int i; foo(i); bar(); } it compiles fine for me. However, I'm not absolutely sure what the "correct" behaviour according to the C++-standard would be. Axel
Re: Gprof can account for less than 1/3 of execution time?!?!
Hi Jon, On Mon, Feb 22, 2010 at 08:43:31AM -0600, Jon Turner wrote: > You're not listening. I am using -pg and the program is statically > linked. The concern I am raising is not about the function counting, > but the reported running times, which are determined by sampling > (read the gprof manual, if this is news to you). > > In this case, the mcount overhead cannot account for the discrepancy, > since that would cause gprof to OVER-estimate the run time, while > in this case it is UNDER-estimating. It's missing about 70% of the > actual running time in the program. Well, іn fact I expect gprof to UNDER-estimate the runtime: The processor needs time in order to do the profiling (count, how often a function was called from which function; measure the times, ...) Now: - the external "time" command will INCLUDE theses times into the reported runtime (it can't distinguish between operations done by your code and by the profiling-code) - I would expect the profiling code to EXCLUDE theses times - because they only pollute the profiling data: When I try to optimize the code based on the profiling-data, I'm not interested in the question how much time was used for the profiling-code, but I'm only interested in the time used in MY code. So: - "time" will give the total runtime (your code + profiling-code) - the gprof-output will (probably) give the runtime of your code, without the profiling code and that means, that gprof should underestimate the runtime. Well, that's what I believe, I never checked it carefully. In addition, you have another place where gprof underestimates the runtime (as already mentioned): - when you link a library which was compiled without -pg, its runtime will be neglected by gprof, but not by "time". Are the standard-libraries (glibc for example) to which you link compiled with "-pg" ? if not, time spend in "printf" or "std::cout" or ... will be neglected by gprof too. - when you call a Kernel-function, which runs in Kernel space, it will be included by "time" - but not by "gprof". HTH, Axel
Re: rationale for eliding modifications to string constants
Hello Uday, On Tue, Sep 14, 2010 at 11:50:11PM +0530, Uday P. Khedker wrote: > [..] > The point is: in your program is is only a pointer. When you pass s > as a parameter to printf, the compiler assumes that only s is being > used so the (effective) assignment > >*s = 'H' > > is deleted as dead code when optimization is enabled. I can't believe your argumentation is correct. Wouldn't that mean: When I have a code, where I only pass the pointer to a function like: void f(int *); int main(){ int *s = (int *)malloc(100,sizeof(int)); for(int i = 0; i < 100; ++i) s[i] = 0; f(s); free(s); } The compiler would be allowed to erase the complete for-loop? And thus the initialization of the array? Or I did misunderstand your argumentation... Axel
Re: Maybe bug in call function to static declaration variable?
Hi Gilberto, On Sun, Nov 14, 2010 at 09:47:43AM -0500, Gilberto Cuba Ricardo wrote: > Hi colleagues, > > The follow program is an abstraction of on application where it > produce an error in runtime and i don't know why it's success. > > The program compile very good in all cases with Visual Studio 2005, > 2008, 2010, MinGW 4.5.1 on Windows 7 and with GCC 4.3 on GNU Debian. > Though, it produce an error in runtime when it's compiled with MinGW > or GCC and next it's executed. > > Anybody can help me to distinguish whether it's an error of my source > code or a bug of gcc? I believe it's a problem of your code. If I reduce your example code to a minimal example showing the problem, I obtain: void type_schema(); struct sponge_object_schema { sponge_object_schema(){ type_schema(); } }; void type_schema() { static sponge_object_schema result; }; int main() { type_schema(); } This creates the same runtime-error: terminate called after throwing an instance of '__gnu_cxx::recursive_init_error' what(): std::exception In this more simple example, one can see the problem: In order to create the static object "result" in the function "type_schema", the function "type_schema" is called itself (from the constructor needed for "type"): this is not possible: - the code executes "type_schema", and allocates memory for the variable "result". - then the constructor "sponge_object_schema" is called. - the constructor calls "type_schema" - and now in "type_shema", it is not possible to access/use the static object "result", as its constructor is NOT FINISHED YET So you have a problem. I have no idea, whether the compiler could/should detect this problem at compile-time (well, in this particular example it could, but in general it is impossible), but at least it's detected at runtime :-) In your example code, the same thing happens: "type_schema" calls the constructor for the static object -- but then "type_schema" is again called from this constructor. I don't see a way how the compiler COULD create working code which solves this problem -- For your code it would be necessary to USE the static object before its constructor is finished... HTH, Axel
Re: const char wd[6] = "Wednes", is that legal?
Hi Joakim, On Tue, Nov 30, 2010 at 03:40:12PM +0100, Joakim Tjernlund wrote: > gcc 4.4.5, powerpc32 does not fail > const char wd[6] = "Wednes"; > even though wd only has room for 6 chars. Is this intended? Which language are you using? ;-) In C++, it's forbidden (there has to be enough space for the implied trailing "\0". In C whoever, it's legal -- you obtain an array of 6 characters, without a trailing "\0" ... Axel
Re: Dumb idea for accelerating FOSS development
Hi, On Wed, Jan 12, 2011 at 01:43:51PM +0100, Basile Starynkevitch wrote: > On Wed, Jan 12, 2011 at 06:07:48AM -0500, Bill Cox wrote: > > Unfortunately, while I could implement this idea in a few days, the > > red tape would keep it in limbo so long that I'll likely die of old > > age before it gets into Debian Stable. Oh, well... here's the dumb > > idea anyway... In short, support a syntax in gcc like: > > > > $ gcc myprog.c -lgit://github/~waywardgeek/sonic=0.1 > > > > In theory, this would cause gcc to do the following: > > > > - Check and see if the requested library has already been > > downloaded and built, and still in the cache > > - If not, download the latest compatible signed version, verify > > the signature, and compile it > > - link to the library in the cache > > At a first glance, I find your idea crazy but nice (but what about header > files *.h of the requested library?). I would be delighted to have it. Maybe > others don't think that way (in particular, those not working on Linux, and > those not working on a compiler running with a network connection). > > Very probably ccache is the better place to implement that, since it already > do > some (preprocessed) source code cache. http://ccache.samba.org/ > > However, my personal feeling is that GCC is quite conservative on the user > features it is accepting. So I won't bet that your idea will be positively > accepted. Well, it is not exactly what you are asking for, but the depot_tools used in the chromium developement might be a solution: http://www.chromium.org/developers/how-tos/depottools The can keep track of different libraries checkout out from svn or git repositories, and calling "gclient sync" connects to all repositories belonging to the project and verifies that all files are up-to-date. May be that would be a better starting point than using gcc? Axel
Re: Proposal for automatic generation of c++ header files
On Fri, Jan 14, 2011 at 05:17:12PM +0200, Achilleas Margaritis wrote: > On Fri, Jan 14, 2011 at 4:58 PM, Jonathan Wakely > wrote: > > On 14 January 2011 13:26, Achilleas Margaritis wrote: > >> My proposal does not change the language in any way, it only is a > >> copy-and-paste job. > > > > That's not true, your example with an inline member function > > demonstrates that the compiler must be changed to support your > > proposal, so that functions defined inline are given a non-inline > > definition that can be linked to by other translation units. > > > > If it was a copy'n'paste job, it could be done by an external tool, > > which you've disputed. > > My proposal doesn't change anything of the language from the > programmer's perspective. I think the point Jonathan wanted to make is the following: your original example does not compile -- and can not compile without a change of the language. If you create by hand the auto-include file you proposed: main.cpp: #include "foo.hpp" int main() { Foo *foo = new Foo; foo->bar(); foos.push_back(foo); } foo.cpp: #include class Foo { public: void bar() {} }; std::list foos; static int data = 0; foo.hpp: #ifndef FOO_HPP #define FOO_HPP #include class Foo { public: void bar(); }; extern std::list foos; #endif //FOO_HPP There is a violation of the C++-standard: - when main.cpp is compiled, the compiler reads "foo.hpp" -- and it learns that the class "Foo" has a member-function "bar" which can be call from within main.cpp -- so main.cpp is compiled without problem. - when "foo.cpp" is compiled, the compiler does not read "foo.hpp" and thus it sees that the function "bar" is defined INLINE. So the compiler will NOT export Foo::bar() -- it will be impossible to link to Foo::bar() from another compilation unit. - finally, you try to link both compilation units. Result: main() tries to call a function "Foo::bar()" -- but that does not exist ==> compilation error. On my machine, I get exactly that: g++ main.cpp foo.cpp /tmp/ccszFpug.o: In function `main': main.cpp:(.text+0x27): undefined reference to `Foo::bar()' collect2: ld returned 1 exit status So in fact you have to change the language, I believe (at least it is necessary to remove the rule "if a member function is defined inline in a class, it is marked as "inline" and NOT exported"). But may be there are also other problems? HTH, Axel
Re: Proposal for automatic generation of c++ header files
On Fri, Jan 14, 2011 at 05:39:58PM +0200, Achilleas Margaritis wrote: > > [...] > > There is a violation of the C++-standard: > > - when main.cpp is compiled, the compiler reads "foo.hpp" -- and it > > learns that the class "Foo" has a member-function "bar" which can be > > call from within main.cpp -- so main.cpp is compiled without problem. > > - when "foo.cpp" is compiled, the compiler does not read "foo.hpp" and > > thus it sees that the function "bar" is defined INLINE. So the > > compiler will NOT export Foo::bar() -- it will be impossible to > > link to Foo::bar() from another compilation unit. > > - finally, you try to link both compilation units. Result: main() tries > > to call a function "Foo::bar()" -- but that does not exist ==> > > compilation error. > > On my machine, I get exactly that: > > g++ main.cpp foo.cpp > > /tmp/ccszFpug.o: In function `main': > > main.cpp:(.text+0x27): undefined reference to `Foo::bar()' > > collect2: ld returned 1 exit status > [...] > There is a solution to that: the compiler, knowing that foo::bar is > not an inline function, it does not inline the function but it > automatically compiles the relevant symbol in the foo.o object file. I agree, one can solve it -- but with a change of the language. And for example I use the fact that member-functions which are defined inline ARE inline (e.g. to speedup trivial access functions). > > The trick is to let the compiler know that foo::bar is not an inline > function. The information that foo::bar is not an inline function is > contained in the header, as I've shown: > > foo.hpp: > #ifndef FOO_HPP > #define FOO_HPP > #include > class Foo { > public: >void bar(); > }; > extern std::list foos; > #endif //FOO_HPP > > So, if the compiler was informed about foo::bar not being inlined, it > could then produce the appropriate symbol. This could happen if the > autogenerated header is automatically included when the implementation > file that produced the autogenerated header is compiled. But that is not possible, as in this case you violate the C++-Standard: Adding '#include "foo.hpp"' to foo.cpp in the example results in the fact that class Foo is two times defined, which is illegal C++ -- and in addition, the two definitions differ (once "bar" is inline, once it isn't). So the compiler would need to realize in addition that "foo.hpp" is an autogenerated file -- and thus the compiler would have to use different compilation rules. > > The compiler could check if there is an autogenerated header in the > same folder as the implementation file; if there is, then it is > included automatically in the implementation file. > > Then the compiler manages the clash of symbols as needed. But with that everything becomes much more complex: - When the compiler compiles "foo.cpp" -- how does he already know that there is a "pragma autoinclude" in another file (here: main.cpp)? Either you have to guarantee that "main.cpp" is compiled before "foo.cpp" -- or you have to include the information "foo.hpp will be autogenerated" also in the file "foo.cpp" - How can the compiler detect that the file "foo.hpp" is autgenerated -- and thus a different language-standard has to be used to treat the class "Foo"? (allowing redefinition of the class; ignoring the fact that the two class-definition differ, ...) -- just try adding '#include "foo.hpp"' in the file foo.cpp, this results in: g++ foo.cpp foo.cpp:4: error: redefinition of ‘class Foo’ foo.hpp:6: error: previous definition of ‘class Foo’ - the code is no longer understandable by other compilers: it is impossible to write by hand a "replacement header" with which an unpatched compiler (without this new extension) could compile the code (at least I don't see a possible way) So I think, this extension would make it necessary at least: - to change the language standard (and add special rules how classes defined in an autogenerated-header are treated) - to add also in "foo.cpp" the information that "foo.hpp" will be autogenerated - to mark "foo.hpp" as being autogenerated And it will be impossible to compile such a code with another compiler (which does NOT know those special rules), even if one supplies by hand the generated header files. Axel
Re: Program editor programming c++
Hi, On Thu, May 29, 2008 at 03:08:34AM -0700, Lopezio wrote: > #include "iostream" > int main(){ > printf("olare"); > return 0; > } > I get error when compile it with gcc ola.cpp -o ola.exe but it works in > rhide environment. Well, your example is neither valid C-code, nor valid C++-code: - iostream belongs to C++, and not c - printf is declared in stdio.h, for C - you should use #include instead of "iostream". With "", gcc searches only in the current directory (and in all directories given given as include directories on command line) - the filename should end on ".c" instead of ".cpp". ".cpp" is understood as C++-code by gcc - If you see nothing in the output: add a newlin "\n" to the printf-command - If you compile using "gcc", the compiler does not link to the C++-libraries. use "g++" instead. If you use (C-version, ola.c) #include int main(){ printf("olare\n"); return 0; } it should work with gcc ola.c -o ola.exe. This also works with g++ ola.c -o ola.exe or as gc ola.cpp -o ola.exe if you want As C++ version, I would propose (in ola.cpp): #include int main(){ std::cout << "olare" << std::endl; } with g++ ola.cpp -o ola.exe The "best" programming environment depends on what you like - I'm using vim HTH, Axel