Use compiler documentation to see difference between O2 and O3
and make your choice (: for example - gcc. Here you can found recommendation to use O2 for stability.
You can use this macro for removing flags:
macro(remove_cxx_flag flag)
string(REPLACE "${flag}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endmacro()
[usage]
macro(remove_cxx_flag flag)
string(REPLACE "${flag}" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
endmacro()
message(${CMAKE_CXX_FLAGS_RELEASE}) # print "-O3 -DNDEBUG"
remove_cxx_flag("-O3")
message(${CMAKE_CXX_FLAGS_RELEASE}) # print "-DNDEBUG"
Here is used macro because you need to update variable from parent scope, read this - http://www.cmake.org/cmake/help/v2.8.10/cmake.html#command:macro (or you can use function with PARENT_SCOPE modifier)
NDEBUG used for disabling assert, see What is the NDEBUG preprocessor macro used for (on different platforms)? for more info.