Getting current post ID in functions.php

I believe this should work in all cases – whether you are in the loop or not. (In a widget, chances are you are not in the loop)

Mind you, outside the loop, this will work very well on single pages or posts, but might not display the post you want on other types of pages. (home page, category pages, …) In those cases, you might want to add a condition to only run your code on a singular page, using WordPress’ is_singular function…

Anyway, here’s a revised version of your code:

function filter_query( $query ) {
    if(in_the_loop()) $post_id = get_the_ID();
    else $post_id = get_queried_object_id();
    if($post_id) {
        if(empty($query['post__not_in'])) $query['post__not_in'] = array(); // that way if someone else already has stuff in $query['post__not_in'], we won't override it but append to it...
        $query['post__not_in'][] = $post_id;
    }
    return $query;
}
add_filter('wpc_query', 'filter_query', 1 );

Hope this helps!