OK, let's revisit #include for a minute. When the compiler hit the #include directive it will add the content of that file in-place of that directive and then will recursively scan the content for other #include for expansion.

This is because a header file may look like this:

// FileA.hpp

#define MACRO1 1
#define MACRO2 "some value"

#ifndef DEBUG
#   define M_D 3.14
#endif

#define MACRO3 3
#define MACRO4 "some other value"

// end FileA.hpp

Such file will cause the compiler to scan each time it got included to insert the defined macros outside the #ifndef.

and here comes #pragma once to instruct the compiler that when it get executed such file will not get included again. see the following example

// FileB.hpp

#ifdef PART_1
# define VALUE 1
# pragma once
#endif
#ifdef PART_2
# define VALUE 2
#endif

// end FileB.hpp

// main.cpp
#include <iostream>
int main()
{
#include "FileB.hpp"  // has no effect since the test macros not defined
#ifdef VALUE
    std::cout << "value is defined\n";   // will not get printed
#endif
#define PART_1
    std::cout << "PART_1 defined\n";

#include "FileB.hpp" // VALUE will get defined as well as the pragma once
    std::cout << "value is :" << VALUE << '\n'; // will print 1

#undef PART_1 
    std::cout << "PART_1 undefined\n"; 
#define PART_2 // has no effect now
    std::cout << "PART_2 defined\n"; 
#include "FileB.hpp" // the file already marked with #pragma once

    std::cout << "value is :" << VALUE << '\n'; // will print 1 again
    return 0;
}

the final result will be

PART_1 defined 
value is :1
PART_1 undefined
PART_2 defined
value is :1

The #pragma once is optimization over the the inclusion guard. This proposal is to add the #include once as a standard way to mark a file as already included when the compiler execute it. so the FileB.hpp will be written in the following way and it will give the same behavior.

// FileB.hpp

#ifdef PART_1
# define VALUE 1
# include once
#endif
#ifdef PART_2
# define VALUE 2
#endif

// end FileB.hpp

this will not remove #pragma once or the inclusion guard technique as the first is a compiler-specific and the later is a valid preprocessor construct. I will just be an addition that tells the compiler to stop including that header file in any subsequent calls for it but in a unified manner.