From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27859 invoked by alias); 25 Sep 2011 16:34:06 -0000 Received: (qmail 27532 invoked by uid 22791); 25 Sep 2011 16:34:05 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SARE_HELO_EQ_CUST,SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from lo.gmane.org (HELO lo.gmane.org) (80.91.229.12) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 25 Sep 2011 16:33:51 +0000 Received: from list by lo.gmane.org with local (Exim 4.69) (envelope-from ) id 1R7reI-0007Lo-2i for gcc@gcc.gnu.org; Sun, 25 Sep 2011 18:33:50 +0200 Received: from 121.79-160-103.customer.lyse.net ([79.160.103.121]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 25 Sep 2011 18:33:50 +0200 Received: from david.brown by 121.79-160-103.customer.lyse.net with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Sun, 25 Sep 2011 18:33:50 +0200 To: gcc@gcc.gnu.org From: David Brown Subject: Re: Volatile qualification on pointer and data Date: Sun, 25 Sep 2011 22:05:00 -0000 Message-ID: <4E7F57E2.7000204@hesbynett.no> References: <4E7A3209.10508@gjlay.de> <4E7DFB31.9010906@westcontrol.com> <4E7F4575.1030308@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: David Brown , gcc@gcc.gnu.org User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.22) Gecko/20110906 Fedora/3.1.14-1.fc14 Thunderbird/3.1.14 In-Reply-To: <4E7F4575.1030308@gmail.com> X-IsSubscribed: yes Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org X-SW-Source: 2011-09/txt/msg00293.txt.bz2 On 25/09/11 17:15, Dave Korn wrote: > On 25/09/2011 13:56, David Brown wrote: > >> There is a big difference between defining an object as "const", and >> merely declaring it as const or accessing it as const. When you access >> it as const, you are saying "/I/ won't change the object with this >> access". When you declare an object as const (such as an extern >> object), you are saying "/I/ won't change this object". When you >> /define/ an object as const, as you do with a "static const", you are >> saying "this object is constant. It will never change value - you (the >> toolchain) can safely place it in read-only memory that cannot ever >> change value". >> >> And then you make it volatile, telling the compiler "this object might >> change unexpectedly, or use values written to it unexpectedly". >> >> If someone could explain to me how this could have real-world usage, I >> think it would be easier for me (and others) to be sure of what it >> really means. > > Just because it's static doesn't mean the address can't escape: > > /* May read or write to dest, according to direction flag. */ > extern void start_dma_xfer (void *dest, unsigned int size, bool direction, > uint64_t bus_addr); > > /* We don't want to change this ourselves, and nor do we want the symbol > to be externally visible. */ > static const volatile char *dma_buffer[BUFFERSIZE]; > > [ ... later, in a function ... ] > > start_dma_transfer (&dma_buffer[0], size, DIRECTION_DMA_TO_MEMORY, devaddr); > > > A bit contrived perhaps, but start_dma_transfer (or some similar function) > might be part of the OS or written in assembly and so necessarily C-type-safe. > > cheers, > DaveK > > I can see that as a possibility, though to me it reads as bad style. I'm aware that taking the address of a static object can let it "escape", and mentioned that possibility in other posts - it will certainly force the object to be created in memory. However, I just don't see why a buffer like this would be defined "const" - it's not constant, so what are you trying to achieve by saying "const"? To answer that, you have to first say /why/ anyone would use the "const" qualifier in the first place. There are five reasons I can think of. First, you have compatibility with other code and types. Then you have error-checking - if you know you will not change an object, you make it "const" to let the compiler check that you haven't changed it by mistake. Then there is optimisation - by telling the compiler that the object won't change value, you let it generate better code (such as using "static const" instead of old-fashioned "#define" or enum constants). Next, you define objects as "const" to let the toolchain place the object in read-only memory - this is very important for small embedded systems running from flash memory. Finally, you use "const" as documentation - you use it when it makes it clearer what the code is doing, why it is doing it, or how it is doing it. So what advantages would there be in declaring a volatile buffer like this to be "const"? At best, you are helping the compiler check that you don't accidentally write to it in your own code. It is dangerous regarding optimisation - you definitely don't want the compiler to optimise the buffer, yet this whole discussion started because some compilers /do/ optimise such code (rightly or wrongly). You don't want the toolchain to put it read-only memory (as noted by another poster, doing so would be against the standards - but toolchain writers are not infallible, and weird corner-cases like this are where mistakes are less likely to be spotted and fixed). So does the "const" make the program clearer to the code writer, and other readers? I would say it has the opposite effect, and leaves a reader wondering what it is supposed to mean - the buffer is clearly not meant to be constant, so why is it declared "const"? When I write code, I almost always define objects as "const" when possible. But in this case there would be no doubt in my mind - that buffer is /not/ constant, and should not be defined as "const" even if it happened to compile and run correctly. I am aware that this is a stylistic choice. But I don't see it as good programming to push boundaries with "risky" code that might or might not work depending on how the compiler writers interpreted the standards - especially when it makes the code less clear to human readers. From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25578 invoked by alias); 25 Sep 2011 16:33:57 -0000 Received: (qmail 25569 invoked by uid 22791); 25 Sep 2011 16:33:56 -0000 X-SWARE-Spam-Status: No, hits=-1.4 required=5.0 tests=AWL,BAYES_00,SPF_NEUTRAL X-Spam-Check-By: sourceware.org Received: from asav4.lyse.net (HELO asav4.lyse.net) (81.167.36.150) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 25 Sep 2011 16:33:42 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by asav4.lyse.net (Postfix) with ESMTP id D0F156C169; Sun, 25 Sep 2011 18:33:40 +0200 (CEST) Received: from zebra.redhouse.homelinux.net (121.79-160-103.customer.lyse.net [79.160.103.121]) by asav4.lyse.net (Postfix) with ESMTP id 2A6756C15D; Sun, 25 Sep 2011 18:33:38 +0200 (CEST) Received: from [192.168.4.160] (lion [192.168.4.160]) by zebra.redhouse.homelinux.net (Postfix) with ESMTP id DD4636FECB; Sun, 25 Sep 2011 18:33:38 +0200 (CEST) Message-ID: <4E7F57E2.7000204@hesbynett.no> Date: Sun, 25 Sep 2011 22:05:00 -0000 From: David Brown User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.22) Gecko/20110906 Fedora/3.1.14-1.fc14 Thunderbird/3.1.14 MIME-Version: 1.0 Newsgroups: gmane.comp.gcc.devel To: Dave Korn CC: David Brown , gcc@gcc.gnu.org Subject: Re: Volatile qualification on pointer and data References: <4E7A3209.10508@gjlay.de> <4E7DFB31.9010906@westcontrol.com> <4E7F4575.1030308@gmail.com> In-Reply-To: <4E7F4575.1030308@gmail.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org X-SW-Source: 2011-09/txt/msg00292.txt.bz2 Message-ID: <20110925220500.tsApVXP6JeshqCJDQ7v3lVKWM51IrsoBe7T93EGZp3U@z> On 25/09/11 17:15, Dave Korn wrote: > On 25/09/2011 13:56, David Brown wrote: > >> There is a big difference between defining an object as "const", and >> merely declaring it as const or accessing it as const. When you access >> it as const, you are saying "/I/ won't change the object with this >> access". When you declare an object as const (such as an extern >> object), you are saying "/I/ won't change this object". When you >> /define/ an object as const, as you do with a "static const", you are >> saying "this object is constant. It will never change value - you (the >> toolchain) can safely place it in read-only memory that cannot ever >> change value". >> >> And then you make it volatile, telling the compiler "this object might >> change unexpectedly, or use values written to it unexpectedly". >> >> If someone could explain to me how this could have real-world usage, I >> think it would be easier for me (and others) to be sure of what it >> really means. > > Just because it's static doesn't mean the address can't escape: > > /* May read or write to dest, according to direction flag. */ > extern void start_dma_xfer (void *dest, unsigned int size, bool direction, > uint64_t bus_addr); > > /* We don't want to change this ourselves, and nor do we want the symbol > to be externally visible. */ > static const volatile char *dma_buffer[BUFFERSIZE]; > > [ ... later, in a function ... ] > > start_dma_transfer (&dma_buffer[0], size, DIRECTION_DMA_TO_MEMORY, devaddr); > > > A bit contrived perhaps, but start_dma_transfer (or some similar function) > might be part of the OS or written in assembly and so necessarily C-type-safe. > > cheers, > DaveK > > I can see that as a possibility, though to me it reads as bad style. I'm aware that taking the address of a static object can let it "escape", and mentioned that possibility in other posts - it will certainly force the object to be created in memory. However, I just don't see why a buffer like this would be defined "const" - it's not constant, so what are you trying to achieve by saying "const"? To answer that, you have to first say /why/ anyone would use the "const" qualifier in the first place. There are five reasons I can think of. First, you have compatibility with other code and types. Then you have error-checking - if you know you will not change an object, you make it "const" to let the compiler check that you haven't changed it by mistake. Then there is optimisation - by telling the compiler that the object won't change value, you let it generate better code (such as using "static const" instead of old-fashioned "#define" or enum constants). Next, you define objects as "const" to let the toolchain place the object in read-only memory - this is very important for small embedded systems running from flash memory. Finally, you use "const" as documentation - you use it when it makes it clearer what the code is doing, why it is doing it, or how it is doing it. So what advantages would there be in declaring a volatile buffer like this to be "const"? At best, you are helping the compiler check that you don't accidentally write to it in your own code. It is dangerous regarding optimisation - you definitely don't want the compiler to optimise the buffer, yet this whole discussion started because some compilers /do/ optimise such code (rightly or wrongly). You don't want the toolchain to put it read-only memory (as noted by another poster, doing so would be against the standards - but toolchain writers are not infallible, and weird corner-cases like this are where mistakes are less likely to be spotted and fixed). So does the "const" make the program clearer to the code writer, and other readers? I would say it has the opposite effect, and leaves a reader wondering what it is supposed to mean - the buffer is clearly not meant to be constant, so why is it declared "const"? When I write code, I almost always define objects as "const" when possible. But in this case there would be no doubt in my mind - that buffer is /not/ constant, and should not be defined as "const" even if it happened to compile and run correctly. I am aware that this is a stylistic choice. But I don't see it as good programming to push boundaries with "risky" code that might or might not work depending on how the compiler writers interpreted the standards - especially when it makes the code less clear to human readers.