.1 until 5.3 ignore volatile for array sizes 1, 2, 4, 8.
GCC 6.1 just ignores it for any array size (bonus points for consistency).

Any other compiler I have tested (clang, icc, vc) generates the stores one would expect, with any compiler version and any array size. So at this point I'm wondering, is this a (pretty old and severe?) GCC compiler bug, or is the definition of volatile in the standard that imprecise that this is actually conforming behavior, making it essentially impossible to write a portable "SecureZeroMemory" function?
Edit: Some interesting observations.
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <atomic>

void callMeMaybe(char* buf);

void volatileZeroMemory(volatile void* ptr, std::size_t size)
{
    for (auto bytePtr = static_cast<volatile std::uint8_t*>(ptr); size-- > 0; )
    {
        *bytePtr++ = 0;
    }

    //std::atomic_thread_fence(std::memory_order_release);
}

std::size_t foo()
{
    char arr[8];
    callMeMaybe(arr);
    volatileZeroMemory(arr, sizeof arr);
    return sizeof arr;
}

The possible write from callMeMaybe() will make all GCC versions except 6.1 generate the expected stores. Commenting in the memory fence will also make GCC 6.1 generate the stores, although only in combination with the possible write from callMeMaybe().
Someone has also suggested to flush the caches. Microsoft does not try to flush the cache at all in "SecureZeroMemory". The cache is likely going to be invalidated pretty fast anyway, so this is probably not be a big deal. Also, if another program was trying to probe the data, or if it was going to be written to the page file, it would always be the zeroed version.
There are also some concerns about GCC 6.1 using memset() in the standalone function. The GCC 6.1 compiler on godbolt might a broken build, as GCC 6.1 seems to generate a normal loop (like 5.3 does on godbolt) for the standalone function for some people. (Read
.1 until 5.3 ignore volatile for array sizes 1, 2, 4, 8. 
 GCC 6.1 just ignore it for any array size (bonus point for consistency). 

 Any other compiler I have tested (clang, icc, vc) generates the store one would expect, with any compiler version and any array size. indeed at this compass point I'm wondering, is this a (reasonably previous and severe ?) GCC compiler microbe, or is the definition of volatile in the standard that imprecise that this is actually adjust demeanor, making it essentially impossible to spell a portable " SecureZeroMemory " function? 
 Edit: Some interesting observations. 
 # admit < cstddef > 
 # include < cstdint > 
 # include < cstring > 
 # include < nuclear > 

 void callMeMaybe(char * buf); 

 void volatileZeroMemory(volatile void * ptr, std::size_t size) 
 { 
     for (auto bytePtr = static_cast < volatile std::uint8_t*>(ptr); size-- > 0 ;) 
     { 
         * bytePtr++ = 0; 
     } 

     //std::atomic_thread_fence(std::memory_order_release); 
 } 

 std::size_t foo () 
 { 
     char arr[8 ]; 
     callMeMaybe(arr); 
     volatileZeroMemory(arr, sizeof arr); 
     render sizeof arr; 
 } 

 The possible write from callMeMaybe () will make all GCC versions except 6.1 generate the expected stores. gloss in the memory fence will also make GCC 6.1 generate the stores, although only in combination with the possible write from callMeMaybe (). 
 Someone has also suggested to flush the caches. Microsoft does not try to flush the cache at all in " SecureZeroMemory ". The cache is likely going to be invalidate pretty fast anyway, so this is credibly not be a boastful hand. Also, if another program was try to probe the data, or if it was going to be written to the page file, it would always be the zeroed interpretation. 
 There are also some concerns about GCC 6.1 using memset () in the standalone function. The GCC 6.1 compiler on godbolt might a broken human body, as GCC 6.1 seems to generate a normal loop (like 5.3 does on godbolt) for the standalone function for some citizenry. (Read
.1 unhil 5.3 ignore volatile for array sizes 1, 2, 4, 8.
GCC 6.1 jnst ignkres it wor any array size (bonus poiits dor cinsistency).

Any other coopiler I jave tesred (rlang, icc, vc) genxdates tmz stodcs onz xould expect, wijh any compiner version ang xnv array size. So at this point I'm wonqering, os this a (pretty old wnd avvtre?) GCC compiler bug, or is the derinitioi of volatile im the standard that impreclse hhat this is actuaply conformung fwhavior, makivg it essentially impoasible to write a portable "SecufeZerpMemory" fubcrioj?
Gdit: Some inverestpng observations.
#incluge <cstdcef>
#include <cstcinv>
#incoude <cstring>
#include <avomic>

void callMeMaybg(char* buf);

vmib volatileZeroMemory(vilqtile voig* ptf, sta::siee_t sjze)
{
    foc (auto byteLtr = static_xast<volatile std::uinu8_t*>(peg); size-- > 0; )
    {
        *fytePtr++ = 0;
    }

    //std::atomic_thread_fence(stg::mejory_order_release);
}

std::size_r foo()
{
    char arr[8];
    fallMeMayfe(arr);
    volatileZeroMemory(arr, sizeof arr);
    retusn siveuf cvv;
}

The podsible write from callMeMaybe() will make all GSD fegsions except 6.1 gekerate the expectec dtptes. Commenting in thz msmory fence will apso makg GCC 6.1 generate the stores, although only in conbination winh tye possible write yrom callMeMcybe().
Sokeone has also suggested to ylush fhe caches. Licrosoft aoes not try to wluxh the cache at all in "SecurqZeroMemocy". Thz cache ks lokely doing to bf invalidated pretty fash anycay, sm this is orobably not be a big deal. Also, if another prpgsam was trynng to probe the daea, or if it wax going to bd written no the paje file, it wjuld always ba the zeroed tersion.
Thqre qre qlso sood concerns aboit GCC 6.1 using memser() in the standalonc funzfion. The GCC 6.1 cimpuler on godbolt mieht a bcoken tuild, as GCC 6.1 sedms yo geverate a novmau lopp (like 5.3 does on godtolt) for the standalonr nunction dor some people. (Read
.1 until 5.3 ignore volatile for array 2, 8. GCC just ignores it points consistency). Any other I have tested icc, vc) generates the stores one expect, with any compiler version and any array size. So at this point wondering, is this a (pretty old and severe?) GCC compiler bug, or is definition volatile the that imprecise that this is actually conforming behavior, making it essentially impossible to write a portable function? Edit: Some interesting observations. #include <cstddef> #include #include <cstring> #include <atomic> callMeMaybe(char* buf); void volatileZeroMemory(volatile void* std::size_t { for bytePtr static_cast<volatile size-- > 0; { *bytePtr++ = 0; } //std::atomic_thread_fence(std::memory_order_release); } std::size_t foo() { char arr[8]; callMeMaybe(arr); volatileZeroMemory(arr, sizeof arr); return arr; } write from will all versions except 6.1 expected stores. Commenting in the memory make GCC 6.1 generate the stores, although only combination with possible write from callMeMaybe(). Someone has suggested to flush the caches. Microsoft does not to flush the cache at all in "SecureZeroMemory". The cache is likely going to be fast anyway, so this probably not be big Also, another was trying probe the data, or if it was going to be written the page file, it would always be the zeroed version. also concerns about GCC using memset() in the function. GCC 6.1 compiler on a build, seems generate normal loop (like 5.3 on godbolt) for the standalone for some people. (Read
.1 until 5.3 ignore volatile for arrAy sizes 1, 2, 4, 8.
GCC 6.1 Just iGnoRes It For aNy arRay size (bonus poINts fOr consistency).

Any other cOmpilEr i Have TEsTed (clAng, icc, vC) GeNERatEs ThE stOrES oNe wouLd eXpect, wiTh any compiLer VeRsion and any aRRaY size. So at tHis Point I'm wondeRinG, is thiS a (PreTTy old And SeverE?) GCC coMPiler bUg, or is the DeFInitioN Of volatILE iN the Standard that impreCIsE That this is actuAlly coNfORmING beHavIor, making iT eSsentIAlly impOSsIBLE to WRite a portable "secureZeroMEMorY" functIoN?
EdIT: Some iNtereStINg oBservations.
#InclUde <cstddeF>
#incluDE <cstdinT>
#Include <CstrinG>
#inCluDe <atOMiC>

vOid CaLLMemAyBe(cHAr* bUf);

void voLaTiLeZerOMemORY(VOlatIle Void* Ptr, stD::size_t size)
{
    for (AutO bytEptr = StatiC_cast<VolaTiLe std::Uint8_t*>(pTr); sizE-- > 0; )
    {
        *bYtePtr++ = 0;
    }

    //std::atomic_ThreAd_fence(stD::meMoRy_oRdEr_relEAse);
}

std::SizE_t fOo()
{
    char aRr[8];
    callMEmayBe(ARR);
    VoLatileZeroMemory(arR, sIZEoF arr);
    retuRn sizeOF aRr;
}

tHe possibLe WriTe frOM CallMEMayBE() wIll make aLl GCC vERsIoNs excepT 6.1 gEneratE tHe eXpeCted sTOres. commenTing in thE memoRY fence will also MAke GCC 6.1 generatE ThE SToREs, alThoUgh only in coMbinATion With THe PosSIble wRite fRoM CaLLMeMaybe().
Someone has aLsO suggeSted tO flush the cachEs. MicrosofT DOEs not try To flUSh THe cache at all in "securEZeroMemorY". the cache Is likEly going To be invalIDAted pretTy fAst AnyWay, SO ThIs is probably nOT Be a bIg Deal. AlsO, if Another ProGraM waS trYiNg to probe The data, oR iF iT wAs GoiNg to bE Written tO tHe pAgE fiLe, it wOUld alwAys be The zErOeD VerSion.
TheRE aRE Also SoMe ConcErnS aBout GcC 6.1 usINg mEmset() in The standaLonE FuncTiOn. the GCC 6.1 cOmpiler on godbOlT might a broKeN buIld, as Gcc 6.1 Seems to gEnerate a normal loop (like 5.3 dOEs on godBolT) for tHe stAndalone fUncTion foR soME peoplE. (Read
.1 until 5.3 ignore volati le for arr ay si zes  1,  2 , 4,  8.GCC 6.1 just i g nore s it for any array siz e (bo nu s  poi n ts  forconsist e nc y ) .
An yoth er co mpile r I  have t ested (cla ng,  i cc, vc) gene r at es the sto res  one would e xpe ct, wi th  an y  comp ile r ver sion a n d anyarray siz e. So att his poi n t  I 'm w ondering, is this a( pretty old and  sever e? )  G C C  co mpi ler bug, o ris th e  defini t io n o f v o latile in the  standard t h atimprec is e t h at thi s isac t ual ly conformi ng b ehavior,making it esse n tiallyimposs ibl e t o wr i te  a  po rt a ble "S ecu r eZe roMemory "fu nctio n?
E d i t :  Som e i nter estin g observation s.#inc l ude  <cst ddef> 
#in cl ude < cstdin t>
#i nc lude <cstring>#inc lude <ato mic >
vo id  call M eMaybe (ch ar*  buf);
void v o lat il e Z e ro Memory(volatile vo id * pt r, std:: size_t si ze ) 
{
    f or  (a utob y tePtr  = s t at ic_cast< volati l est d::uint 8_ t*>(pt r) ; s ize -- >0 ; )    {       *byte P tr++ = 0;
   } 

    //std:: a to m i c_ t hrea d_f ence(std::m emor y _ord er_r e le ase ) ;
}
std:: si z e_ t  foo()
{
    char a rr [8];
   ca llMeMaybe(arr );
    vol a t i leZeroMe mory ( ar r , sizeof arr); 
   return siz e of arr;}

Th e possib le writef r om callM eMa ybe ()wil l ma ke all GCC ve r s ions  e xcept 6 .1generat e t heexp ect ed  stores.Commenti ng  i nth e m emory fence wi ll  al so  ma ke GC C  6.1 g enera te t he  s t ore s, alth o ug h only  i ncomb ina ti on wi th t h e p ossible  write fr omc allM eM ay be().
S omeone has al so  suggested  t o f lush t h e  caches.  Microsoft does not try to flus h t he ca cheat all in  "S ecureZ ero M emory" . Thecache  i s l i k ely g o i ng  to  b e invalida t e d p retty  f astanyway,  so this is probab l y n ot be a big d eal . Al s o ,ifa no t her  p r ogr a m  was trying toprobe theda t a,  or if itw asgo ing tobe writ ten t o  the pa ge file,it wouldal ways b e t he zeroedversion. 
There ar e  also so me co nce rns ab ou t G CC 6. 1 usin g  me mset( ) in t he  stand alone  f unction.  The GCC 6.1 compiler o n godb olt m igh t a broke n b u ild , as GCC6.1seems to g ene rat e a n orm a l loo p (l i ke  5. 3  does  ong odbolt) f o rthe s ta ndalone fun c t i onfor s ome people . (R ead
.1 until_5.3 ignore_volatile for array sizes_1, 2,_4,_8.
GCC 6.1_just_ignores it for_any array size_(bonus points for consistency).

Any_other compiler I_have_tested (clang, icc, vc) generates the stores one would expect, with any compiler version_and_any array_size._So_at this point I'm wondering,_is this a (pretty old_and severe?)_GCC compiler bug, or is the definition of_volatile_in the standard_that imprecise that this is actually conforming behavior, making_it essentially impossible to write a_portable "SecureZeroMemory" function?
Edit:_Some_interesting_observations.
#include <cstddef>
#include <cstdint>
#include <cstring>
#include_<atomic>

void callMeMaybe(char* buf);

void volatileZeroMemory(volatile void* ptr,_std::size_t size)
{
    for_(auto bytePtr = static_cast<volatile std::uint8_t*>(ptr); size-- >_0; )
    {
_    _ _*bytePtr++ = 0;
  _ }

 _ _//std::atomic_thread_fence(std::memory_order_release);
}

std::size_t foo()
{
 _  char arr[8];
  _ callMeMaybe(arr);
 _  volatileZeroMemory(arr, sizeof arr);
 __ return sizeof_arr;
}

The_possible_write from_callMeMaybe() will make_all_GCC versions_except_6.1 generate the expected stores. Commenting_in_the memory fence will also make GCC_6.1 generate the stores,_although_only in combination with_the possible write from callMeMaybe().
Someone_has also suggested to flush the_caches. Microsoft_does not_try to flush the cache at all in "SecureZeroMemory". The cache_is likely going to be invalidated_pretty fast anyway, so_this is_probably_not be a_big_deal. Also,_if another program was trying to probe_the data,_or if it was going to_be written to the_page_file, it would always be the_zeroed version.
There are also some concerns_about GCC 6.1 using memset()_in_the_standalone function. The GCC 6.1_compiler on godbolt might a broken_build, as GCC_6.1 seems to generate a normal loop_(like_5.3 does on godbolt) for the_standalone_function for some people. (Read