Thread: Prevent optimization of zero-ed memory.

  1. #1
    Registered User
    Join Date
    Oct 2019
    Posts
    6

    Prevent optimization of zero-ed memory.

    Code:
    #include <stdio.h>
    #include <string.h>
    #define BUFFLENGTH 100
    int main() {
       char buffer[BUFFLENGTH+1];
       memset(buffer,0,BUFFLENGTH+1);
       fgets(buffer,BUFFLENGTH,stdin);
       buffer[strcspn(buffer,"\n")] = 0;
       printf("%s.\n",buffer);
       return 0;
    }
    This snippet of code should demonstrate my problem. GCC's optimization level of 0 will make this perform as expected: that is, any trailing newlines get removed. But at any higher optimization levels, GCC seems to decide that the assignment to zero is unnecessary, and vanishes it away.

    I can, of course, make "buffer" a volatile char array, but in my real code (this is just a simplified version for clarity), GCC complains with a warning whenever I try to use "buffer" for anything else; e.g. passing it to a function, unless I re-cast it to a char * or const char *. I know of no reason why I shouldn't cast like this (to my understanding, a volatile char is the same size as a char, just treated differently by the compiler), but doing this for each invocation of "buffer" seems both annoying and ugly.

    Is there any other way I can hint to GCC not to optimize this specific statement?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Since it is impossible to assign to 0, I'm guessing you mean the opposite, that is, this line?
    Code:
    buffer[strcspn(buffer,"\n")] = 0;
    If so, that's weird: the statement is not a candidate to be removed as part of optimisation to begin with. Just to check: how did you know that the compiler is optimising it away at higher optimisation levels? For example, is this by observing actual output from test input, and if so what was your test input? Or was this by observing assembly output, and if so, what was the assembly output?

    EDIT:
    Scratch my request for test input, I realised that it was quite silly to ask for that. I compiled your program with gcc 7.4.0 on Ubuntu 18.04 with -O3 and could not replicate behaviour indicating that that line has been optimised away.

    By the way, fgets will only read at most BUFFLENGTH - 1 characters from stdin, so are you sure you need to allocate BUFFLENGTH + 1 characters for the array?
    Last edited by laserlight; 10-18-2019 at 02:28 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Oct 2019
    Posts
    6
    Quote Originally Posted by laserlight View Post
    Since it is impossible to assign to 0, I'm guessing you mean the opposite, that is, this line?
    Code:
    buffer[strcspn(buffer,"\n")] = 0;
    Assignment of 0 to the first character in "buffer" to have a newline, then. シ Sorry for the confusion.

    If so, that's weird: the statement is not a candidate to be removed as part of optimisation to begin with. Just to check: how did you know that the compiler is optimising it away at higher optimisation levels? For example, is this by observing actual output from test input, and if so what was your test input? Or was this by observing assembly output, and if so, what was the assembly output?
    Test input. I can't read assembly, unfortunately -- I'm just a hobbyist, and haven't yet devoted time to learning it. Anyway, anything works, but I just ran it using the input "Test". On -O0, the output was

    Code:
    Test.
    O3:

    Code:
    Test
    .
    If your statement that this shouldn't be optimized is true, I'm stumped as to how this is happening.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What version of gcc did you use to compile?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    FYI: "O3" is often broken in GCC on Windows OSes.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  6. #6
    Registered User
    Join Date
    Oct 2019
    Posts
    6
    Quote Originally Posted by laserlight View Post
    What version of gcc did you use to compile?
    9.2.0.

    You know, I apologize for most likely wasting your time, but the code I posted is no longer exhibiting the issue after I changed parts of it to test, then reverted to what I wrote here. I assume I must have had something different in my test code causing this issue, but I genuinely don't know what it would be, since I copy-pasted from my test file to the board.

    That said, I'm still having this problem in my "real" code -- appearing when optimizations are turned on, and disappearing when they're off. It's designed roughly the same way -- strcspn-ing a char array -- so I guess I'll work on reproducing this issue in a smaller chunk of code.

    Anyway, thanks for being willing to help. I apologize, again, for what was probably a stupid user error.

    stahta01, thanks for the advice, but I'm running a Linux distro

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I guess upgrading compiler isn't an option then

    Unfortunately in your real code, this could be due to undefined behaviour interacting with compiler optimisation, rather than a compiler bug. But if it is due to a compiler bug involved writing a zero to previously zeroed memory, then that suggests a workaround: don't zero the memory. Now, if it must have static storage duration then that's not an option, but otherwise it might work. If you really need the trailing unused portion of the array to be zeroed, you could always do a memset after fgets instead.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 17
    Last Post: 03-10-2013, 11:35 AM
  2. C Optimization for Memory Allocation
    By fguy817817 in forum C Programming
    Replies: 15
    Last Post: 12-15-2009, 02:34 PM
  3. prevent piping?
    By barneygumble742 in forum C++ Programming
    Replies: 2
    Last Post: 12-29-2005, 01:07 AM
  4. Memory Use and Optimization
    By spike in forum C Programming
    Replies: 3
    Last Post: 02-11-2002, 01:50 PM

Tags for this Thread